• 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 "mir_builder.h"
17 #include "mir_symbol_builder.h"
18 
19 namespace maple {
20 // This is for compiler-generated metadata 1-level struct
AddIntFieldConst(const MIRStructType & sType,MIRAggConst & newConst,uint32 fieldID,int64 constValue)21 void MIRBuilder::AddIntFieldConst(const MIRStructType &sType, MIRAggConst &newConst, uint32 fieldID, int64 constValue)
22 {
23     auto *fieldConst =
24         GlobalTables::GetIntConstTable().GetOrCreateIntConst(constValue, *sType.GetElemType(fieldID - 1));
25     newConst.AddItem(fieldConst, fieldID);
26 }
27 
28 // This is for compiler-generated metadata 1-level struct
AddAddrofFieldConst(const MIRStructType & structType,MIRAggConst & newConst,uint32 fieldID,const MIRSymbol & fieldSymbol)29 void MIRBuilder::AddAddrofFieldConst(const MIRStructType &structType, MIRAggConst &newConst, uint32 fieldID,
30                                      const MIRSymbol &fieldSymbol)
31 {
32     AddrofNode *fieldExpr = CreateExprAddrof(0, fieldSymbol, mirModule->GetMemPool());
33     auto *fieldConst = mirModule->GetMemPool()->New<MIRAddrofConst>(fieldExpr->GetStIdx(), fieldExpr->GetFieldID(),
34                                                                     *structType.GetElemType(fieldID - 1));
35     newConst.AddItem(fieldConst, fieldID);
36 }
37 
38 // This is for compiler-generated metadata 1-level struct
AddAddroffuncFieldConst(const MIRStructType & structType,MIRAggConst & newConst,uint32 fieldID,const MIRSymbol & funcSymbol)39 void MIRBuilder::AddAddroffuncFieldConst(const MIRStructType &structType, MIRAggConst &newConst, uint32 fieldID,
40                                          const MIRSymbol &funcSymbol)
41 {
42     MIRConst *fieldConst = nullptr;
43     MIRFunction *vMethod = funcSymbol.GetFunction();
44     if (vMethod->IsAbstract()) {
45         fieldConst = GlobalTables::GetIntConstTable().GetOrCreateIntConst(0, *structType.GetElemType(fieldID - 1));
46     } else {
47         AddroffuncNode *addrofFuncExpr =
48             CreateExprAddroffunc(funcSymbol.GetFunction()->GetPuidx(), mirModule->GetMemPool());
49         fieldConst = mirModule->GetMemPool()->New<MIRAddroffuncConst>(addrofFuncExpr->GetPUIdx(),
50                                                                       *structType.GetElemType(fieldID - 1));
51     }
52     newConst.AddItem(fieldConst, fieldID);
53 }
54 
55 // fieldID is continuously being updated during traversal;
56 // when the field is found, its field id is returned via fieldID
TraverseToNamedField(MIRStructType & structType,GStrIdx nameIdx,uint32 & fieldID)57 bool MIRBuilder::TraverseToNamedField(MIRStructType &structType, GStrIdx nameIdx, uint32 &fieldID)
58 {
59     TyIdx tid(0);
60     return TraverseToNamedFieldWithTypeAndMatchStyle(structType, nameIdx, tid, fieldID, kMatchAnyField);
61 }
62 
63 // traverse parent first but match self first.
TraverseToNamedFieldWithType(MIRStructType & structType,GStrIdx nameIdx,TyIdx typeIdx,uint32 & fieldID,uint32 & idx)64 void MIRBuilder::TraverseToNamedFieldWithType(MIRStructType &structType, GStrIdx nameIdx, TyIdx typeIdx,
65                                               uint32 &fieldID, uint32 &idx)
66 {
67     if (structType.IsIncomplete()) {
68         (void)incompleteTypeRefedSet.insert(structType.GetTypeIndex());
69     }
70     // process parent
71     if (structType.GetKind() == kTypeClass || structType.GetKind() == kTypeClassIncomplete) {
72         auto &classType = static_cast<MIRClassType &>(structType);
73         MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(classType.GetParentTyIdx());
74         auto *parentType = static_cast<MIRStructType *>(type);
75         if (parentType != nullptr) {
76             ++fieldID;
77             TraverseToNamedFieldWithType(*parentType, nameIdx, typeIdx, fieldID, idx);
78         }
79     }
80     for (uint32 fieldIdx = 0; fieldIdx < structType.GetFieldsSize(); ++fieldIdx) {
81         ++fieldID;
82         TyIdx fieldTyIdx = structType.GetFieldsElemt(fieldIdx).second.first;
83         MIRType *fieldType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(fieldTyIdx);
84         if (structType.GetFieldsElemt(fieldIdx).first == nameIdx) {
85             if (typeIdx == 0u || fieldTyIdx == typeIdx) {
86                 idx = fieldID;
87                 continue;
88             }
89             // for pointer type, check their pointed type
90             MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(typeIdx);
91             if (type->IsOfSameType(*fieldType)) {
92                 idx = fieldID;
93             }
94         }
95 
96         if (fieldType->IsStructType()) {
97             auto *subStructType = static_cast<MIRStructType *>(fieldType);
98             TraverseToNamedFieldWithType(*subStructType, nameIdx, typeIdx, fieldID, idx);
99         }
100     }
101 }
102 
103 // fieldID is continuously being updated during traversal;
104 // when the field is found, its field id is returned via fieldID
105 //
106 // typeidx: TyIdx(0) means do not check types.
107 // matchstyle: 0: do not match but traverse to update fieldID
108 //             1: match top level field only
109 //             2: match any field
110 //             4: traverse parent first
111 //          0xc: do not match but traverse to update fieldID, traverse parent first, found in child
TraverseToNamedFieldWithTypeAndMatchStyle(MIRStructType & structType,GStrIdx nameIdx,TyIdx typeIdx,uint32 & fieldID,unsigned int matchStyle)112 bool MIRBuilder::TraverseToNamedFieldWithTypeAndMatchStyle(MIRStructType &structType, GStrIdx nameIdx, TyIdx typeIdx,
113                                                            uint32 &fieldID, unsigned int matchStyle)
114 {
115     if (structType.IsIncomplete()) {
116         (void)incompleteTypeRefedSet.insert(structType.GetTypeIndex());
117     }
118     if (matchStyle & kParentFirst) {
119         // process parent
120         if ((structType.GetKind() != kTypeClass) && (structType.GetKind() != kTypeClassIncomplete)) {
121             return false;
122         }
123 
124         auto &classType = static_cast<MIRClassType &>(structType);
125         MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(classType.GetParentTyIdx());
126         auto *parentType = static_cast<MIRStructType *>(type);
127         if (parentType != nullptr) {
128             ++fieldID;
129             if (matchStyle == (kFoundInChild | kParentFirst | kUpdateFieldID)) {
130                 matchStyle = kParentFirst;
131                 uint32 idxBackup = nameIdx;
132                 nameIdx.reset();
133                 // do not match but traverse to update fieldID, traverse parent first
134                 TraverseToNamedFieldWithTypeAndMatchStyle(*parentType, nameIdx, typeIdx, fieldID, matchStyle);
135                 nameIdx.reset(idxBackup);
136             } else if (TraverseToNamedFieldWithTypeAndMatchStyle(*parentType, nameIdx, typeIdx, fieldID, matchStyle)) {
137                 return true;
138             }
139         }
140     }
141     for (uint32 fieldIdx = 0; fieldIdx < structType.GetFieldsSize(); ++fieldIdx) {
142         ++fieldID;
143         TyIdx fieldTyIdx = structType.GetFieldsElemt(fieldIdx).second.first;
144         MIRType *fieldType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(fieldTyIdx);
145         DEBUG_ASSERT(fieldType != nullptr, "fieldType is null");
146         if (matchStyle && structType.GetFieldsElemt(fieldIdx).first == nameIdx) {
147             if (typeIdx == 0u || fieldTyIdx == typeIdx ||
148                 fieldType->IsOfSameType(*GlobalTables::GetTypeTable().GetTypeFromTyIdx(typeIdx))) {
149                 return true;
150             }
151         }
152         unsigned int style = matchStyle & kMatchAnyField;
153         if (fieldType->IsStructType()) {
154             auto *subStructType = static_cast<MIRStructType *>(fieldType);
155             if (TraverseToNamedFieldWithTypeAndMatchStyle(*subStructType, nameIdx, typeIdx, fieldID, style)) {
156                 return true;
157             }
158         }
159     }
160     return false;
161 }
162 
GetStructFieldIDFromNameAndType(MIRType & type,const std::string & name,TyIdx idx,unsigned int matchStyle)163 FieldID MIRBuilder::GetStructFieldIDFromNameAndType(MIRType &type, const std::string &name, TyIdx idx,
164                                                     unsigned int matchStyle)
165 {
166     auto &structType = static_cast<MIRStructType &>(type);
167     uint32 fieldID = 0;
168     GStrIdx strIdx = GetStringIndex(name);
169     if (TraverseToNamedFieldWithTypeAndMatchStyle(structType, strIdx, idx, fieldID, matchStyle)) {
170         return fieldID;
171     }
172     return 0;
173 }
174 
GetStructFieldIDFromNameAndType(MIRType & type,const std::string & name,TyIdx idx)175 FieldID MIRBuilder::GetStructFieldIDFromNameAndType(MIRType &type, const std::string &name, TyIdx idx)
176 {
177     return GetStructFieldIDFromNameAndType(type, name, idx, kMatchAnyField);
178 }
179 
GetStructFieldIDFromNameAndTypeParentFirst(MIRType & type,const std::string & name,TyIdx idx)180 FieldID MIRBuilder::GetStructFieldIDFromNameAndTypeParentFirst(MIRType &type, const std::string &name, TyIdx idx)
181 {
182     return GetStructFieldIDFromNameAndType(type, name, idx, kParentFirst);
183 }
184 
GetStructFieldIDFromNameAndTypeParentFirstFoundInChild(MIRType & type,const std::string & name,TyIdx idx)185 FieldID MIRBuilder::GetStructFieldIDFromNameAndTypeParentFirstFoundInChild(MIRType &type, const std::string &name,
186                                                                            TyIdx idx)
187 {
188     // do not match but traverse to update fieldID, traverse parent first, found in child
189     return GetStructFieldIDFromNameAndType(type, name, idx, kFoundInChild | kParentFirst | kUpdateFieldID);
190 }
191 
GetStructFieldIDFromFieldName(MIRType & type,const std::string & name)192 FieldID MIRBuilder::GetStructFieldIDFromFieldName(MIRType &type, const std::string &name)
193 {
194     return GetStructFieldIDFromNameAndType(type, name, TyIdx(0), kMatchAnyField);
195 }
196 
GetStructFieldIDFromFieldNameParentFirst(MIRType * type,const std::string & name)197 FieldID MIRBuilder::GetStructFieldIDFromFieldNameParentFirst(MIRType *type, const std::string &name)
198 {
199     if (type == nullptr) {
200         return 0;
201     }
202     return GetStructFieldIDFromNameAndType(*type, name, TyIdx(0), kParentFirst);
203 }
204 
SetStructFieldIDFromFieldName(MIRStructType & structType,const std::string & name,GStrIdx newStrIdx,const MIRType & newFieldType)205 void MIRBuilder::SetStructFieldIDFromFieldName(MIRStructType &structType, const std::string &name, GStrIdx newStrIdx,
206                                                const MIRType &newFieldType)
207 {
208     uint32 fieldID = 0;
209     GStrIdx strIdx = GetStringIndex(name);
210     while (true) {
211         if (structType.GetElemStrIdx(fieldID) == strIdx) {
212             if (newStrIdx != 0u) {
213                 structType.SetElemStrIdx(fieldID, newStrIdx);
214             }
215             structType.SetElemtTyIdx(fieldID, newFieldType.GetTypeIndex());
216             return;
217         }
218         ++fieldID;
219     }
220 }
221 
222 // create a function named str
GetOrCreateFunction(const std::string & str,TyIdx retTyIdx)223 MIRFunction *MIRBuilder::GetOrCreateFunction(const std::string &str, TyIdx retTyIdx)
224 {
225     GStrIdx strIdx = GetStringIndex(str);
226     MIRSymbol *funcSt = nullptr;
227     if (strIdx != 0u) {
228         funcSt = GlobalTables::GetGsymTable().GetSymbolFromStrIdx(strIdx);
229         if (funcSt == nullptr) {
230             funcSt = CreateSymbol(TyIdx(0), strIdx, kStFunc, kScText, nullptr, kScopeGlobal);
231         } else {
232             DEBUG_ASSERT(funcSt->GetSKind() == kStFunc, "runtime check error");
233             return funcSt->GetFunction();
234         }
235     } else {
236         strIdx = GetOrCreateStringIndex(str);
237         funcSt = CreateSymbol(TyIdx(0), strIdx, kStFunc, kScText, nullptr, kScopeGlobal);
238     }
239     auto *fn = mirModule->GetMemPool()->New<MIRFunction>(mirModule, funcSt->GetStIdx());
240     fn->SetPuidx(GlobalTables::GetFunctionTable().GetFuncTable().size());
241     MIRFuncType funcType;
242     funcType.SetRetTyIdx(retTyIdx);
243     auto funcTyIdx = GlobalTables::GetTypeTable().GetOrCreateMIRType(&funcType);
244     auto *funcTypeInTypeTable = static_cast<MIRFuncType *>(GlobalTables::GetTypeTable().GetTypeFromTyIdx(funcTyIdx));
245     fn->SetMIRFuncType(funcTypeInTypeTable);
246     fn->SetReturnTyIdx(retTyIdx);
247     GlobalTables::GetFunctionTable().GetFuncTable().push_back(fn);
248     funcSt->SetFunction(fn);
249     funcSt->SetTyIdx(funcTyIdx);
250     return fn;
251 }
252 
GetFunctionFromSymbol(const MIRSymbol & funcSymbol)253 MIRFunction *MIRBuilder::GetFunctionFromSymbol(const MIRSymbol &funcSymbol)
254 {
255     DEBUG_ASSERT(funcSymbol.GetSKind() == kStFunc, "Symbol %s is not a function symbol", funcSymbol.GetName().c_str());
256     return funcSymbol.GetFunction();
257 }
258 
GetFunctionFromName(const std::string & str)259 MIRFunction *MIRBuilder::GetFunctionFromName(const std::string &str)
260 {
261     auto *funcSymbol =
262         GlobalTables::GetGsymTable().GetSymbolFromStrIdx(GlobalTables::GetStrTable().GetStrIdxFromName(str));
263     return funcSymbol != nullptr ? GetFunctionFromSymbol(*funcSymbol) : nullptr;
264 }
265 
GetFunctionFromStidx(StIdx stIdx)266 MIRFunction *MIRBuilder::GetFunctionFromStidx(StIdx stIdx)
267 {
268     auto *funcSymbol = GlobalTables::GetGsymTable().GetSymbolFromStidx(stIdx.Idx());
269     return funcSymbol != nullptr ? GetFunctionFromSymbol(*funcSymbol) : nullptr;
270 }
271 
CreateFunction(const std::string & name,const MIRType & returnType,const ArgVector & arguments,bool isVarg,bool createBody) const272 MIRFunction *MIRBuilder::CreateFunction(const std::string &name, const MIRType &returnType, const ArgVector &arguments,
273                                         bool isVarg, bool createBody) const
274 {
275     MIRSymbol *funcSymbol = GlobalTables::GetGsymTable().CreateSymbol(kScopeGlobal);
276     GStrIdx strIdx = GetOrCreateStringIndex(name);
277     funcSymbol->SetNameStrIdx(strIdx);
278     if (!GlobalTables::GetGsymTable().AddToStringSymbolMap(*funcSymbol)) {
279         return nullptr;
280     }
281     funcSymbol->SetStorageClass(kScText);
282     funcSymbol->SetSKind(kStFunc);
283     auto *fn = mirModule->GetMemPool()->New<MIRFunction>(mirModule, funcSymbol->GetStIdx());
284     fn->SetPuidx(GlobalTables::GetFunctionTable().GetFuncTable().size());
285     GlobalTables::GetFunctionTable().GetFuncTable().push_back(fn);
286     std::vector<TyIdx> funcVecType;
287     std::vector<TypeAttrs> funcVecAttrs;
288     for (size_t i = 0; i < arguments.size(); ++i) {
289         MIRType *ty = arguments[i].second;
290         FormalDef formalDef(GetOrCreateStringIndex(arguments[i].first.c_str()), nullptr, ty->GetTypeIndex(),
291                             TypeAttrs());
292         fn->GetFormalDefVec().push_back(formalDef);
293         funcVecType.push_back(ty->GetTypeIndex());
294         funcVecAttrs.push_back(TypeAttrs());
295         if (fn->GetSymTab() != nullptr && formalDef.formalSym != nullptr) {
296             (void)fn->GetSymTab()->AddToStringSymbolMap(*formalDef.formalSym);
297         }
298     }
299     funcSymbol->SetTyIdx(GlobalTables::GetTypeTable()
300                          .GetOrCreateFunctionType(returnType.GetTypeIndex(), funcVecType, funcVecAttrs, isVarg)
301                          ->GetTypeIndex());
302     auto *funcType = static_cast<MIRFuncType *>(funcSymbol->GetType());
303     fn->SetMIRFuncType(funcType);
304     funcSymbol->SetFunction(fn);
305     if (createBody) {
306         fn->NewBody();
307     }
308     return fn;
309 }
310 
CreateFunction(StIdx stIdx,bool addToTable) const311 MIRFunction *MIRBuilder::CreateFunction(StIdx stIdx, bool addToTable) const
312 {
313     auto *fn = mirModule->GetMemPool()->New<MIRFunction>(mirModule, stIdx);
314     fn->SetPuidx(GlobalTables::GetFunctionTable().GetFuncTable().size());
315     if (addToTable) {
316         GlobalTables::GetFunctionTable().GetFuncTable().push_back(fn);
317     }
318 
319     auto *funcType = mirModule->GetMemPool()->New<MIRFuncType>();
320     fn->SetMIRFuncType(funcType);
321     return fn;
322 }
323 
GetOrCreateGlobalDecl(const std::string & str,TyIdx tyIdx,bool & created) const324 MIRSymbol *MIRBuilder::GetOrCreateGlobalDecl(const std::string &str, TyIdx tyIdx, bool &created) const
325 {
326     GStrIdx strIdx = GetStringIndex(str);
327     if (strIdx != 0u) {
328         StIdx stIdx = GlobalTables::GetGsymTable().GetStIdxFromStrIdx(strIdx);
329         if (stIdx.Idx() != 0) {
330             created = false;
331             return GlobalTables::GetGsymTable().GetSymbolFromStidx(stIdx.Idx());
332         }
333     }
334     created = true;
335     strIdx = GetOrCreateStringIndex(str);
336     MIRSymbol *st = GlobalTables::GetGsymTable().CreateSymbol(kScopeGlobal);
337     st->SetNameStrIdx(strIdx);
338     st->SetTyIdx(tyIdx);
339     (void)GlobalTables::GetGsymTable().AddToStringSymbolMap(*st);
340     return st;
341 }
342 
GetOrCreateLocalDecl(const std::string & str,TyIdx tyIdx,MIRSymbolTable & symbolTable,bool & created) const343 MIRSymbol *MIRBuilder::GetOrCreateLocalDecl(const std::string &str, TyIdx tyIdx, MIRSymbolTable &symbolTable,
344                                             bool &created) const
345 {
346     GStrIdx strIdx = GetStringIndex(str);
347     if (strIdx != 0u) {
348         StIdx stIdx = symbolTable.GetStIdxFromStrIdx(strIdx);
349         if (stIdx.Idx() != 0) {
350             created = false;
351             return symbolTable.GetSymbolFromStIdx(stIdx.Idx());
352         }
353     }
354     created = true;
355     strIdx = GetOrCreateStringIndex(str);
356     MIRSymbol *st = symbolTable.CreateSymbol(kScopeLocal);
357     DEBUG_ASSERT(st != nullptr, "null ptr check");
358     st->SetNameStrIdx(strIdx);
359     st->SetTyIdx(tyIdx);
360     (void)symbolTable.AddToStringSymbolMap(*st);
361     return st;
362 }
363 
GetOrCreateDeclInFunc(const std::string & str,const MIRType & type,MIRFunction & func)364 MIRSymbol *MIRBuilder::GetOrCreateDeclInFunc(const std::string &str, const MIRType &type, MIRFunction &func)
365 {
366     MIRSymbolTable *symbolTable = func.GetSymTab();
367     DEBUG_ASSERT(symbolTable != nullptr, "symbol_table is null");
368     bool isCreated = false;
369     MIRSymbol *st = GetOrCreateLocalDecl(str, type.GetTypeIndex(), *symbolTable, isCreated);
370     if (isCreated) {
371         st->SetStorageClass(kScAuto);
372         st->SetSKind(kStVar);
373     }
374     return st;
375 }
376 
GetOrCreateLocalDecl(const std::string & str,const MIRType & type)377 MIRSymbol *MIRBuilder::GetOrCreateLocalDecl(const std::string &str, const MIRType &type)
378 {
379     MIRFunction *currentFunc = GetCurrentFunction();
380     CHECK_FATAL(currentFunc != nullptr, "null ptr check");
381     return GetOrCreateDeclInFunc(str, type, *currentFunc);
382 }
383 
CreateLocalDecl(const std::string & str,const MIRType & type)384 MIRSymbol *MIRBuilder::CreateLocalDecl(const std::string &str, const MIRType &type)
385 {
386     MIRFunction *currentFunctionInner = GetCurrentFunctionNotNull();
387     return MIRSymbolBuilder::Instance().CreateLocalDecl(*currentFunctionInner->GetSymTab(), GetOrCreateStringIndex(str),
388                                                         type);
389 }
390 
GetGlobalDecl(const std::string & str)391 MIRSymbol *MIRBuilder::GetGlobalDecl(const std::string &str)
392 {
393     return MIRSymbolBuilder::Instance().GetGlobalDecl(GetStringIndex(str));
394 }
395 
GetLocalDecl(const std::string & str)396 MIRSymbol *MIRBuilder::GetLocalDecl(const std::string &str)
397 {
398     MIRFunction *currentFunctionInner = GetCurrentFunctionNotNull();
399     return MIRSymbolBuilder::Instance().GetLocalDecl(*currentFunctionInner->GetSymTab(), GetStringIndex(str));
400 }
401 
402 // search the scope hierarchy
GetDecl(const std::string & str)403 MIRSymbol *MIRBuilder::GetDecl(const std::string &str)
404 {
405     GStrIdx strIdx = GetStringIndex(str);
406     MIRSymbol *sym = nullptr;
407     if (strIdx != 0u) {
408         // try to find the decl in local scope first
409         MIRFunction *currentFunctionInner = GetCurrentFunction();
410         if (currentFunctionInner != nullptr) {
411             sym = currentFunctionInner->GetSymTab()->GetSymbolFromStrIdx(strIdx);
412         }
413         if (sym == nullptr) {
414             sym = GlobalTables::GetGsymTable().GetSymbolFromStrIdx(strIdx);
415         }
416     }
417     return sym;
418 }
419 
CreateGlobalDecl(const std::string & str,const MIRType & type,MIRStorageClass sc)420 MIRSymbol *MIRBuilder::CreateGlobalDecl(const std::string &str, const MIRType &type, MIRStorageClass sc)
421 {
422     return MIRSymbolBuilder::Instance().CreateGlobalDecl(GetOrCreateStringIndex(str), type, sc);
423 }
424 
GetOrCreateGlobalDecl(const std::string & str,const MIRType & type)425 MIRSymbol *MIRBuilder::GetOrCreateGlobalDecl(const std::string &str, const MIRType &type)
426 {
427     bool isCreated = false;
428     MIRSymbol *st = GetOrCreateGlobalDecl(str, type.GetTypeIndex(), isCreated);
429     DEBUG_ASSERT(st != nullptr, "null ptr check");
430     if (isCreated) {
431         st->SetStorageClass(kScGlobal);
432         st->SetSKind(kStVar);
433     } else {
434         // Existing symbol may come from anther module. We need to register it
435         // in the current module so that per-module mpl file is self-sustained.
436         mirModule->AddSymbol(st);
437     }
438     MIRConst *cst = GlobalTables::GetConstPool().GetConstFromPool(st->GetNameStrIdx());
439     if (cst != nullptr) {
440         st->SetKonst(cst);
441     }
442     return st;
443 }
444 
GetSymbolFromEnclosingScope(StIdx stIdx) const445 MIRSymbol *MIRBuilder::GetSymbolFromEnclosingScope(StIdx stIdx) const
446 {
447     if (stIdx.FullIdx() == 0) {
448         return nullptr;
449     }
450     if (stIdx.Islocal()) {
451         MIRFunction *fun = GetCurrentFunctionNotNull();
452         MIRSymbol *st = fun->GetSymTab()->GetSymbolFromStIdx(stIdx.Idx());
453         if (st != nullptr) {
454             return st;
455         }
456     }
457     return GlobalTables::GetGsymTable().GetSymbolFromStidx(stIdx.Idx());
458 }
459 
GetSymbol(TyIdx tyIdx,const std::string & name,MIRSymKind mClass,MIRStorageClass sClass,uint8 scpID,bool sameType=false) const460 MIRSymbol *MIRBuilder::GetSymbol(TyIdx tyIdx, const std::string &name, MIRSymKind mClass, MIRStorageClass sClass,
461                                  uint8 scpID, bool sameType = false) const
462 {
463     return GetSymbol(tyIdx, GetOrCreateStringIndex(name), mClass, sClass, scpID, sameType);
464 }
465 
466 // when sametype is true, it means match everything the of the symbol
GetSymbol(TyIdx tyIdx,GStrIdx strIdx,MIRSymKind mClass,MIRStorageClass sClass,uint8 scpID,bool sameType=false) const467 MIRSymbol *MIRBuilder::GetSymbol(TyIdx tyIdx, GStrIdx strIdx, MIRSymKind mClass, MIRStorageClass sClass, uint8 scpID,
468                                  bool sameType = false) const
469 {
470     if (scpID != kScopeGlobal) {
471         ERR(kLncErr, "not yet implemented");
472         return nullptr;
473     }
474     return MIRSymbolBuilder::Instance().GetSymbol(tyIdx, strIdx, mClass, sClass, sameType);
475 }
476 
GetOrCreateSymbol(TyIdx tyIdx,const std::string & name,MIRSymKind mClass,MIRStorageClass sClass,MIRFunction * func,uint8 scpID,bool sametype=false) const477 MIRSymbol *MIRBuilder::GetOrCreateSymbol(TyIdx tyIdx, const std::string &name, MIRSymKind mClass,
478                                          MIRStorageClass sClass, MIRFunction *func, uint8 scpID,
479                                          bool sametype = false) const
480 {
481     return GetOrCreateSymbol(tyIdx, GetOrCreateStringIndex(name), mClass, sClass, func, scpID, sametype);
482 }
483 
GetOrCreateSymbol(TyIdx tyIdx,GStrIdx strIdx,MIRSymKind mClass,MIRStorageClass sClass,MIRFunction * func,uint8 scpID,bool sameType=false) const484 MIRSymbol *MIRBuilder::GetOrCreateSymbol(TyIdx tyIdx, GStrIdx strIdx, MIRSymKind mClass, MIRStorageClass sClass,
485                                          MIRFunction *func, uint8 scpID, bool sameType = false) const
486 {
487     if (MIRSymbol *st = GetSymbol(tyIdx, strIdx, mClass, sClass, scpID, sameType)) {
488         return st;
489     }
490     return CreateSymbol(tyIdx, strIdx, mClass, sClass, func, scpID);
491 }
492 
493 // when func is null, create global symbol, otherwise create local symbol
CreateSymbol(TyIdx tyIdx,const std::string & name,MIRSymKind mClass,MIRStorageClass sClass,MIRFunction * func,uint8 scpID) const494 MIRSymbol *MIRBuilder::CreateSymbol(TyIdx tyIdx, const std::string &name, MIRSymKind mClass, MIRStorageClass sClass,
495                                     MIRFunction *func, uint8 scpID) const
496 {
497     return CreateSymbol(tyIdx, GetOrCreateStringIndex(name), mClass, sClass, func, scpID);
498 }
499 
500 // when func is null, create global symbol, otherwise create local symbol
CreateSymbol(TyIdx tyIdx,GStrIdx strIdx,MIRSymKind mClass,MIRStorageClass sClass,MIRFunction * func,uint8 scpID) const501 MIRSymbol *MIRBuilder::CreateSymbol(TyIdx tyIdx, GStrIdx strIdx, MIRSymKind mClass, MIRStorageClass sClass,
502                                     MIRFunction *func, uint8 scpID) const
503 {
504     return MIRSymbolBuilder::Instance().CreateSymbol(tyIdx, strIdx, mClass, sClass, func, scpID);
505 }
506 
CreateConstStringSymbol(const std::string & symbolName,const std::string & content)507 MIRSymbol *MIRBuilder::CreateConstStringSymbol(const std::string &symbolName, const std::string &content)
508 {
509     auto elemPrimType = PTY_u8;
510     MIRType *type = GlobalTables::GetTypeTable().GetPrimType(elemPrimType);
511     uint32 sizeIn = static_cast<uint32>(content.length());
512     MIRType *arrayTypeWithSize = GlobalTables::GetTypeTable().GetOrCreateArrayType(
513         *GlobalTables::GetTypeTable().GetPrimType(elemPrimType), 1, &sizeIn);
514 
515     if (GetLocalDecl(symbolName)) {
516         return GetLocalDecl(symbolName);
517     }
518     MIRSymbol *arrayVar = GetOrCreateGlobalDecl(symbolName, *arrayTypeWithSize);
519     arrayVar->SetAttr(ATTR_readonly);
520     arrayVar->SetStorageClass(kScFstatic);
521     MIRAggConst *val = mirModule->GetMemPool()->New<MIRAggConst>(*mirModule, *arrayTypeWithSize);
522     for (uint32 i = 0; i < sizeIn; ++i) {
523         MIRConst *cst = mirModule->GetMemPool()->New<MIRIntConst>(content[i], *type);
524         val->PushBack(cst);
525     }
526     // This interface is only for string literal, 0 is added to the end of the string.
527     MIRConst *cst0 = mirModule->GetMemPool()->New<MIRIntConst>(0, *type);
528     val->PushBack(cst0);
529     arrayVar->SetKonst(val);
530     return arrayVar;
531 }
532 
CreatePregFormalSymbol(TyIdx tyIdx,PregIdx pRegIdx,MIRFunction & func) const533 MIRSymbol *MIRBuilder::CreatePregFormalSymbol(TyIdx tyIdx, PregIdx pRegIdx, MIRFunction &func) const
534 {
535     return MIRSymbolBuilder::Instance().CreatePregFormalSymbol(tyIdx, pRegIdx, func);
536 }
537 
CreateConstval(MIRConst * mirConst)538 ConstvalNode *MIRBuilder::CreateConstval(MIRConst *mirConst)
539 {
540     return GetCurrentFuncCodeMp()->New<ConstvalNode>(mirConst->GetType().GetPrimType(), mirConst);
541 }
542 
CreateIntConst(uint64 val,PrimType pty)543 ConstvalNode *MIRBuilder::CreateIntConst(uint64 val, PrimType pty)
544 {
545     auto *mirConst =
546         GlobalTables::GetIntConstTable().GetOrCreateIntConst(val, *GlobalTables::GetTypeTable().GetPrimType(pty));
547     return GetCurrentFuncCodeMp()->New<ConstvalNode>(pty, mirConst);
548 }
549 
CreateFloatConst(float val)550 ConstvalNode *MIRBuilder::CreateFloatConst(float val)
551 {
552     auto *mirConst =
553         GetCurrentFuncDataMp()->New<MIRFloatConst>(val, *GlobalTables::GetTypeTable().GetPrimType(PTY_f32));
554     return GetCurrentFuncCodeMp()->New<ConstvalNode>(PTY_f32, mirConst);
555 }
556 
CreateDoubleConst(double val)557 ConstvalNode *MIRBuilder::CreateDoubleConst(double val)
558 {
559     auto *mirConst =
560         GetCurrentFuncDataMp()->New<MIRDoubleConst>(val, *GlobalTables::GetTypeTable().GetPrimType(PTY_f64));
561     return GetCurrentFuncCodeMp()->New<ConstvalNode>(PTY_f64, mirConst);
562 }
563 
CreateFloat128Const(const uint64 * val)564 ConstvalNode *MIRBuilder::CreateFloat128Const(const uint64 *val)
565 {
566     auto *mirConst =
567         GetCurrentFuncDataMp()->New<MIRFloat128Const>(*val, *GlobalTables::GetTypeTable().GetPrimType(PTY_f128));
568     return GetCurrentFuncCodeMp()->New<ConstvalNode>(PTY_f128, mirConst);
569 }
570 
GetConstInt(MemPool & memPool,int val)571 ConstvalNode *MIRBuilder::GetConstInt(MemPool &memPool, int val)
572 {
573     auto *mirConst =
574         GlobalTables::GetIntConstTable().GetOrCreateIntConst(val, *GlobalTables::GetTypeTable().GetInt64());
575     return memPool.New<ConstvalNode>(PTY_i32, mirConst);
576 }
577 
CreateAddrofConst(BaseNode & node)578 ConstvalNode *MIRBuilder::CreateAddrofConst(BaseNode &node)
579 {
580     DEBUG_ASSERT(node.GetOpCode() == OP_addrof, "illegal op for addrof const");
581     MIRFunction *currentFunctionInner = GetCurrentFunctionNotNull();
582 
583     // determine the type of 'node' and create a pointer type, accordingly
584     auto &aNode = static_cast<AddrofNode &>(node);
585     const MIRSymbol *var = currentFunctionInner->GetLocalOrGlobalSymbol(aNode.GetStIdx());
586     TyIdx ptyIdx = var->GetTyIdx();
587     MIRPtrType ptrType(ptyIdx);
588     ptyIdx = GlobalTables::GetTypeTable().GetOrCreateMIRType(&ptrType);
589     MIRType &exprType = *GlobalTables::GetTypeTable().GetTypeFromTyIdx(ptyIdx);
590     auto *temp = mirModule->GetMemPool()->New<MIRAddrofConst>(aNode.GetStIdx(), aNode.GetFieldID(), exprType);
591     return GetCurrentFuncCodeMp()->New<ConstvalNode>(PTY_ptr, temp);
592 }
593 
CreateAddroffuncConst(const BaseNode & node)594 ConstvalNode *MIRBuilder::CreateAddroffuncConst(const BaseNode &node)
595 {
596     DEBUG_ASSERT(node.GetOpCode() == OP_addroffunc, "illegal op for addroffunc const");
597 
598     const auto &aNode = static_cast<const AddroffuncNode &>(node);
599     MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(aNode.GetPUIdx());
600     TyIdx ptyIdx = f->GetFuncSymbol()->GetTyIdx();
601     MIRPtrType ptrType(ptyIdx);
602     ptyIdx = GlobalTables::GetTypeTable().GetOrCreateMIRType(&ptrType);
603     MIRType *exprType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(ptyIdx);
604     auto *mirConst = mirModule->GetMemPool()->New<MIRAddroffuncConst>(aNode.GetPUIdx(), *exprType);
605     return GetCurrentFuncCodeMp()->New<ConstvalNode>(PTY_ptr, mirConst);
606 }
607 
CreateStrConst(const BaseNode & node)608 ConstvalNode *MIRBuilder::CreateStrConst(const BaseNode &node)
609 {
610     DEBUG_ASSERT(node.GetOpCode() == OP_conststr, "illegal op for conststr const");
611     UStrIdx strIdx = static_cast<const ConststrNode &>(node).GetStrIdx();
612     CHECK_FATAL(PTY_u8 < GlobalTables::GetTypeTable().GetTypeTable().size(),
613                 "index is out of range in MIRBuilder::CreateStrConst");
614     TyIdx tyIdx = GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(PTY_u8))->GetTypeIndex();
615     MIRPtrType ptrType(tyIdx);
616     tyIdx = GlobalTables::GetTypeTable().GetOrCreateMIRType(&ptrType);
617     MIRType *exprType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx);
618     auto *mirConst = mirModule->GetMemPool()->New<MIRStrConst>(strIdx, *exprType);
619     return GetCurrentFuncCodeMp()->New<ConstvalNode>(PTY_ptr, mirConst);
620 }
621 
CreateStr16Const(const BaseNode & node)622 ConstvalNode *MIRBuilder::CreateStr16Const(const BaseNode &node)
623 {
624     DEBUG_ASSERT(node.GetOpCode() == OP_conststr16, "illegal op for conststr16 const");
625     U16StrIdx strIdx = static_cast<const Conststr16Node &>(node).GetStrIdx();
626     CHECK_FATAL(PTY_u16 < GlobalTables::GetTypeTable().GetTypeTable().size(),
627                 "index out of range in MIRBuilder::CreateStr16Const");
628     TyIdx ptyIdx = GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(PTY_u16))->GetTypeIndex();
629     MIRPtrType ptrType(ptyIdx);
630     ptyIdx = GlobalTables::GetTypeTable().GetOrCreateMIRType(&ptrType);
631     MIRType *exprType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(ptyIdx);
632     auto *mirConst = mirModule->GetMemPool()->New<MIRStr16Const>(strIdx, *exprType);
633     return GetCurrentFuncCodeMp()->New<ConstvalNode>(PTY_ptr, mirConst);
634 }
635 
CreateExprSizeoftype(const MIRType & type)636 SizeoftypeNode *MIRBuilder::CreateExprSizeoftype(const MIRType &type)
637 {
638     return GetCurrentFuncCodeMp()->New<SizeoftypeNode>(PTY_u32, type.GetTypeIndex());
639 }
640 
CreateExprFieldsDist(const MIRType & type,FieldID field1,FieldID field2)641 FieldsDistNode *MIRBuilder::CreateExprFieldsDist(const MIRType &type, FieldID field1, FieldID field2)
642 {
643     return GetCurrentFuncCodeMp()->New<FieldsDistNode>(PTY_i32, type.GetTypeIndex(), field1, field2);
644 }
645 
CreateExprAddrof(FieldID fieldID,const MIRSymbol & symbol,MemPool * memPool)646 AddrofNode *MIRBuilder::CreateExprAddrof(FieldID fieldID, const MIRSymbol &symbol, MemPool *memPool)
647 {
648     return CreateExprAddrof(fieldID, symbol.GetStIdx(), memPool);
649 }
650 
CreateExprAddrof(FieldID fieldID,StIdx symbolStIdx,MemPool * memPool)651 AddrofNode *MIRBuilder::CreateExprAddrof(FieldID fieldID, StIdx symbolStIdx, MemPool *memPool)
652 {
653     if (memPool == nullptr) {
654         memPool = GetCurrentFuncCodeMp();
655     }
656     return memPool->New<AddrofNode>(OP_addrof, PTY_ptr, symbolStIdx, fieldID);
657 }
658 
CreateExprAddroffunc(PUIdx puIdx,MemPool * memPool)659 AddroffuncNode *MIRBuilder::CreateExprAddroffunc(PUIdx puIdx, MemPool *memPool)
660 {
661     if (memPool == nullptr) {
662         memPool = GetCurrentFuncCodeMp();
663     }
664     return memPool->New<AddroffuncNode>(PTY_ptr, puIdx);
665 }
666 
CreateExprDread(const MIRType & type,FieldID fieldID,const MIRSymbol & symbol)667 AddrofNode *MIRBuilder::CreateExprDread(const MIRType &type, FieldID fieldID, const MIRSymbol &symbol)
668 {
669     return CreateExprDread(type.GetPrimType(), fieldID, symbol);
670 }
671 
CreateExprDread(PrimType ptyp,FieldID fieldID,const MIRSymbol & symbol)672 AddrofNode *MIRBuilder::CreateExprDread(PrimType ptyp, FieldID fieldID, const MIRSymbol &symbol)
673 {
674     auto *node = GetCurrentFuncCodeMp()->New<AddrofNode>(OP_dread, kPtyInvalid, symbol.GetStIdx(), fieldID);
675     node->SetPrimType(GetRegPrimType(ptyp));
676     return node;
677 }
678 
CreateExprRegread(PrimType pty,PregIdx regIdx)679 RegreadNode *MIRBuilder::CreateExprRegread(PrimType pty, PregIdx regIdx)
680 {
681     return GetCurrentFuncCodeMp()->New<RegreadNode>(pty, regIdx);
682 }
683 
CreateExprDread(MIRType & type,MIRSymbol & symbol)684 AddrofNode *MIRBuilder::CreateExprDread(MIRType &type, MIRSymbol &symbol)
685 {
686     return CreateExprDread(type, 0, symbol);
687 }
688 
CreateExprDread(MIRSymbol & symbol,uint16 fieldID)689 AddrofNode *MIRBuilder::CreateExprDread(MIRSymbol &symbol, uint16 fieldID)
690 {
691     if (fieldID == 0) {
692         return CreateExprDread(symbol);
693     }
694     DEBUG_ASSERT(false, "NYI");
695     return nullptr;
696 }
697 
CreateExprDread(MIRSymbol & symbol)698 AddrofNode *MIRBuilder::CreateExprDread(MIRSymbol &symbol)
699 {
700     return CreateExprDread(*symbol.GetType(), 0, symbol);
701 }
702 
CreateExprDread(PregIdx pregID,PrimType pty)703 AddrofNode *MIRBuilder::CreateExprDread(PregIdx pregID, PrimType pty)
704 {
705     auto *dread = GetCurrentFuncCodeMp()->New<AddrofNode>(OP_dread, pty);
706     dread->SetStFullIdx(pregID);
707     return dread;
708 }
709 
CreateExprDreadoff(Opcode op,PrimType pty,const MIRSymbol & symbol,int32 offset)710 DreadoffNode *MIRBuilder::CreateExprDreadoff(Opcode op, PrimType pty, const MIRSymbol &symbol, int32 offset)
711 {
712     DreadoffNode *node = GetCurrentFuncCodeMp()->New<DreadoffNode>(op, pty);
713     node->stIdx = symbol.GetStIdx();
714     node->offset = offset;
715     return node;
716 }
717 
CreateExprIread(const MIRType & returnType,const MIRType & ptrType,FieldID fieldID,BaseNode * addr)718 IreadNode *MIRBuilder::CreateExprIread(const MIRType &returnType, const MIRType &ptrType, FieldID fieldID,
719                                        BaseNode *addr)
720 {
721     TyIdx returnTypeIdx = returnType.GetTypeIndex();
722     CHECK(returnTypeIdx < GlobalTables::GetTypeTable().GetTypeTable().size(),
723           "index out of range in MIRBuilder::CreateExprIread");
724     DEBUG_ASSERT(fieldID != 0 || ptrType.GetPrimType() != PTY_agg,
725                  "Error: Fieldid should not be 0 when trying to iread a field from type ");
726     PrimType type = GetRegPrimType(returnType.GetPrimType());
727     return GetCurrentFuncCodeMp()->New<IreadNode>(OP_iread, type, ptrType.GetTypeIndex(), fieldID, addr);
728 }
729 
CreateExprIreadoff(PrimType pty,int32 offset,BaseNode * opnd0)730 IreadoffNode *MIRBuilder::CreateExprIreadoff(PrimType pty, int32 offset, BaseNode *opnd0)
731 {
732     return GetCurrentFuncCodeMp()->New<IreadoffNode>(pty, opnd0, offset);
733 }
734 
CreateExprIreadFPoff(PrimType pty,int32 offset)735 IreadFPoffNode *MIRBuilder::CreateExprIreadFPoff(PrimType pty, int32 offset)
736 {
737     return GetCurrentFuncCodeMp()->New<IreadFPoffNode>(pty, offset);
738 }
739 
CreateExprIaddrof(const MIRType & returnType,const MIRType & ptrType,FieldID fieldID,BaseNode * addr)740 IaddrofNode *MIRBuilder::CreateExprIaddrof(const MIRType &returnType, const MIRType &ptrType, FieldID fieldID,
741                                            BaseNode *addr)
742 {
743     IaddrofNode *iAddrOfNode = CreateExprIread(returnType, ptrType, fieldID, addr);
744     iAddrOfNode->SetOpCode(OP_iaddrof);
745     return iAddrOfNode;
746 }
747 
CreateExprIaddrof(PrimType returnTypePty,TyIdx ptrTypeIdx,FieldID fieldID,BaseNode * addr)748 IaddrofNode *MIRBuilder::CreateExprIaddrof(PrimType returnTypePty, TyIdx ptrTypeIdx, FieldID fieldID, BaseNode *addr)
749 {
750     return GetCurrentFuncCodeMp()->New<IreadNode>(OP_iaddrof, returnTypePty, ptrTypeIdx, fieldID, addr);
751 }
752 
CreateExprUnary(Opcode opcode,const MIRType & type,BaseNode * opnd)753 UnaryNode *MIRBuilder::CreateExprUnary(Opcode opcode, const MIRType &type, BaseNode *opnd)
754 {
755     return GetCurrentFuncCodeMp()->New<UnaryNode>(opcode, type.GetPrimType(), opnd);
756 }
757 
CreateExprGCMalloc(Opcode opcode,const MIRType & pType,const MIRType & type)758 GCMallocNode *MIRBuilder::CreateExprGCMalloc(Opcode opcode, const MIRType &pType, const MIRType &type)
759 {
760     return GetCurrentFuncCodeMp()->New<GCMallocNode>(opcode, pType.GetPrimType(), type.GetTypeIndex());
761 }
762 
CreateExprJarrayMalloc(Opcode opcode,const MIRType & pType,const MIRType & type,BaseNode * opnd)763 JarrayMallocNode *MIRBuilder::CreateExprJarrayMalloc(Opcode opcode, const MIRType &pType, const MIRType &type,
764                                                      BaseNode *opnd)
765 {
766     return GetCurrentFuncCodeMp()->New<JarrayMallocNode>(opcode, pType.GetPrimType(), type.GetTypeIndex(), opnd);
767 }
768 
CreateExprTypeCvt(Opcode o,PrimType toPrimType,PrimType fromPrimType,BaseNode & opnd)769 TypeCvtNode *MIRBuilder::CreateExprTypeCvt(Opcode o, PrimType toPrimType, PrimType fromPrimType, BaseNode &opnd)
770 {
771     return GetCurrentFuncCodeMp()->New<TypeCvtNode>(o, toPrimType, fromPrimType, &opnd);
772 }
773 
CreateExprTypeCvt(Opcode o,const MIRType & type,const MIRType & fromType,BaseNode * opnd)774 TypeCvtNode *MIRBuilder::CreateExprTypeCvt(Opcode o, const MIRType &type, const MIRType &fromType, BaseNode *opnd)
775 {
776     return CreateExprTypeCvt(o, type.GetPrimType(), fromType.GetPrimType(), *opnd);
777 }
778 
CreateExprExtractbits(Opcode o,const MIRType & type,uint32 bOffset,uint32 bSize,BaseNode * opnd)779 ExtractbitsNode *MIRBuilder::CreateExprExtractbits(Opcode o, const MIRType &type, uint32 bOffset, uint32 bSize,
780                                                    BaseNode *opnd)
781 {
782     return CreateExprExtractbits(o, type.GetPrimType(), bOffset, bSize, opnd);
783 }
784 
CreateExprExtractbits(Opcode o,PrimType type,uint32 bOffset,uint32 bSize,BaseNode * opnd)785 ExtractbitsNode *MIRBuilder::CreateExprExtractbits(Opcode o, PrimType type, uint32 bOffset, uint32 bSize,
786                                                    BaseNode *opnd)
787 {
788     return GetCurrentFuncCodeMp()->New<ExtractbitsNode>(o, type, bOffset, bSize, opnd);
789 }
790 
CreateExprDepositbits(Opcode o,PrimType type,uint32 bOffset,uint32 bSize,BaseNode * leftOpnd,BaseNode * rightOpnd)791 DepositbitsNode *MIRBuilder::CreateExprDepositbits(Opcode o, PrimType type, uint32 bOffset, uint32 bSize,
792                                                    BaseNode *leftOpnd, BaseNode *rightOpnd)
793 {
794     return GetCurrentFuncCodeMp()->New<DepositbitsNode>(o, type, bOffset, bSize, leftOpnd, rightOpnd);
795 }
796 
CreateExprRetype(const MIRType & type,const MIRType & fromType,BaseNode * opnd)797 RetypeNode *MIRBuilder::CreateExprRetype(const MIRType &type, const MIRType &fromType, BaseNode *opnd)
798 {
799     return CreateExprRetype(type, fromType.GetPrimType(), opnd);
800 }
801 
CreateExprRetype(const MIRType & type,PrimType fromType,BaseNode * opnd)802 RetypeNode *MIRBuilder::CreateExprRetype(const MIRType &type, PrimType fromType, BaseNode *opnd)
803 {
804     return GetCurrentFuncCodeMp()->New<RetypeNode>(type.GetPrimType(), fromType, type.GetTypeIndex(), opnd);
805 }
806 
CreateExprBinary(Opcode opcode,const MIRType & type,BaseNode * opnd0,BaseNode * opnd1)807 BinaryNode *MIRBuilder::CreateExprBinary(Opcode opcode, const MIRType &type, BaseNode *opnd0, BaseNode *opnd1)
808 {
809     return GetCurrentFuncCodeMp()->New<BinaryNode>(opcode, type.GetPrimType(), opnd0, opnd1);
810 }
811 
CreateExprTernary(Opcode opcode,const MIRType & type,BaseNode * opnd0,BaseNode * opnd1,BaseNode * opnd2)812 TernaryNode *MIRBuilder::CreateExprTernary(Opcode opcode, const MIRType &type, BaseNode *opnd0, BaseNode *opnd1,
813                                            BaseNode *opnd2)
814 {
815     return GetCurrentFuncCodeMp()->New<TernaryNode>(opcode, type.GetPrimType(), opnd0, opnd1, opnd2);
816 }
817 
CreateExprCompare(Opcode opcode,const MIRType & type,const MIRType & opndType,BaseNode * opnd0,BaseNode * opnd1)818 CompareNode *MIRBuilder::CreateExprCompare(Opcode opcode, const MIRType &type, const MIRType &opndType, BaseNode *opnd0,
819                                            BaseNode *opnd1)
820 {
821     return GetCurrentFuncCodeMp()->New<CompareNode>(opcode, type.GetPrimType(), opndType.GetPrimType(), opnd0, opnd1);
822 }
823 
CreateExprArray(const MIRType & arrayType)824 ArrayNode *MIRBuilder::CreateExprArray(const MIRType &arrayType)
825 {
826     MIRType *addrType = GlobalTables::GetTypeTable().GetOrCreatePointerType(arrayType);
827     DEBUG_ASSERT(addrType != nullptr, "addrType is null");
828     auto *arrayNode = GetCurrentFuncCodeMp()->New<ArrayNode>(*GetCurrentFuncCodeMpAllocator(), addrType->GetPrimType(),
829                                                              addrType->GetTypeIndex());
830     arrayNode->SetNumOpnds(0);
831     return arrayNode;
832 }
833 
CreateExprArray(const MIRType & arrayType,BaseNode * op)834 ArrayNode *MIRBuilder::CreateExprArray(const MIRType &arrayType, BaseNode *op)
835 {
836     ArrayNode *arrayNode = CreateExprArray(arrayType);
837     arrayNode->GetNopnd().push_back(op);
838     arrayNode->SetNumOpnds(1);
839     return arrayNode;
840 }
841 
CreateExprArray(const MIRType & arrayType,BaseNode * op1,BaseNode * op2)842 ArrayNode *MIRBuilder::CreateExprArray(const MIRType &arrayType, BaseNode *op1, BaseNode *op2)
843 {
844     ArrayNode *arrayNode = CreateExprArray(arrayType, op1);
845     arrayNode->GetNopnd().push_back(op2);
846     arrayNode->SetNumOpnds(2); // 2 operands
847     return arrayNode;
848 }
849 
CreateExprArray(const MIRType & arrayType,std::vector<BaseNode * > ops)850 ArrayNode *MIRBuilder::CreateExprArray(const MIRType &arrayType, std::vector<BaseNode *> ops)
851 {
852     MIRType *addrType = GlobalTables::GetTypeTable().GetOrCreatePointerType(arrayType);
853     DEBUG_ASSERT(addrType != nullptr, "addrType is null");
854     auto *arrayNode = GetCurrentFuncCodeMp()->New<ArrayNode>(*GetCurrentFuncCodeMpAllocator(), addrType->GetPrimType(),
855                                                              addrType->GetTypeIndex());
856     arrayNode->GetNopnd().insert(arrayNode->GetNopnd().begin(), ops.begin(), ops.end());
857     arrayNode->SetNumOpnds(static_cast<uint8>(ops.size()));
858     return arrayNode;
859 }
860 
CreateExprIntrinsicop(MIRIntrinsicID id,Opcode op,PrimType primType,TyIdx tyIdx,const MapleVector<BaseNode * > & ops)861 IntrinsicopNode *MIRBuilder::CreateExprIntrinsicop(MIRIntrinsicID id, Opcode op, PrimType primType, TyIdx tyIdx,
862                                                    const MapleVector<BaseNode *> &ops)
863 {
864     auto *expr = GetCurrentFuncCodeMp()->New<IntrinsicopNode>(*GetCurrentFuncCodeMpAllocator(), op, primType);
865     expr->SetIntrinsic(id);
866     expr->SetNOpnd(ops);
867     expr->SetNumOpnds(ops.size());
868     if (op == OP_intrinsicopwithtype) {
869         expr->SetTyIdx(tyIdx);
870     }
871     return expr;
872 }
873 
CreateExprIntrinsicop(MIRIntrinsicID idx,Opcode opCode,const MIRType & type,const MapleVector<BaseNode * > & ops)874 IntrinsicopNode *MIRBuilder::CreateExprIntrinsicop(MIRIntrinsicID idx, Opcode opCode, const MIRType &type,
875                                                    const MapleVector<BaseNode *> &ops)
876 {
877     return CreateExprIntrinsicop(idx, opCode, type.GetPrimType(), type.GetTypeIndex(), ops);
878 }
879 
CreateStmtDassign(const MIRSymbol & symbol,FieldID fieldID,BaseNode * src)880 DassignNode *MIRBuilder::CreateStmtDassign(const MIRSymbol &symbol, FieldID fieldID, BaseNode *src)
881 {
882     return GetCurrentFuncCodeMp()->New<DassignNode>(src, symbol.GetStIdx(), fieldID);
883 }
884 
CreateStmtRegassign(PrimType pty,PregIdx regIdx,BaseNode * src)885 RegassignNode *MIRBuilder::CreateStmtRegassign(PrimType pty, PregIdx regIdx, BaseNode *src)
886 {
887     return GetCurrentFuncCodeMp()->New<RegassignNode>(pty, regIdx, src);
888 }
889 
CreateStmtDassign(StIdx sIdx,FieldID fieldID,BaseNode * src)890 DassignNode *MIRBuilder::CreateStmtDassign(StIdx sIdx, FieldID fieldID, BaseNode *src)
891 {
892     return GetCurrentFuncCodeMp()->New<DassignNode>(src, sIdx, fieldID);
893 }
894 
CreateStmtIassign(const MIRType & type,FieldID fieldID,BaseNode * addr,BaseNode * src)895 IassignNode *MIRBuilder::CreateStmtIassign(const MIRType &type, FieldID fieldID, BaseNode *addr, BaseNode *src)
896 {
897     return GetCurrentFuncCodeMp()->New<IassignNode>(type.GetTypeIndex(), fieldID, addr, src);
898 }
899 
CreateStmtIassignoff(PrimType pty,int32 offset,BaseNode * addr,BaseNode * src)900 IassignoffNode *MIRBuilder::CreateStmtIassignoff(PrimType pty, int32 offset, BaseNode *addr, BaseNode *src)
901 {
902     return GetCurrentFuncCodeMp()->New<IassignoffNode>(pty, offset, addr, src);
903 }
904 
CreateStmtIassignFPoff(Opcode op,PrimType pty,int32 offset,BaseNode * src)905 IassignFPoffNode *MIRBuilder::CreateStmtIassignFPoff(Opcode op, PrimType pty, int32 offset, BaseNode *src)
906 {
907     return GetCurrentFuncCodeMp()->New<IassignFPoffNode>(op, pty, offset, src);
908 }
909 
CreateStmtCall(PUIdx puIdx,const MapleVector<BaseNode * > & args,Opcode opCode)910 CallNode *MIRBuilder::CreateStmtCall(PUIdx puIdx, const MapleVector<BaseNode *> &args, Opcode opCode)
911 {
912     auto *stmt = GetCurrentFuncCodeMp()->New<CallNode>(*GetCurrentFuncCodeMpAllocator(), opCode, puIdx, TyIdx());
913     stmt->SetNOpnd(args);
914     stmt->SetNumOpnds(args.size());
915     return stmt;
916 }
917 
CreateStmtCall(const std::string & callee,const MapleVector<BaseNode * > & args)918 CallNode *MIRBuilder::CreateStmtCall(const std::string &callee, const MapleVector<BaseNode *> &args)
919 {
920     GStrIdx strIdx = GlobalTables::GetStrTable().GetStrIdxFromName(callee);
921     StIdx stIdx = GlobalTables::GetGsymTable().GetStIdxFromStrIdx(strIdx);
922     MIRSymbol *st = GlobalTables::GetGsymTable().GetSymbolFromStidx(stIdx.Idx());
923     DEBUG_ASSERT(st != nullptr, "MIRSymbol st is null");
924     MIRFunction *func = st->GetFunction();
925     return CreateStmtCall(func->GetPuidx(), args, OP_call);
926 }
927 
CreateStmtIcall(const MapleVector<BaseNode * > & args)928 IcallNode *MIRBuilder::CreateStmtIcall(const MapleVector<BaseNode *> &args)
929 {
930     auto *stmt = GetCurrentFuncCodeMp()->New<IcallNode>(*GetCurrentFuncCodeMpAllocator(), OP_icall);
931     DEBUG_ASSERT(stmt != nullptr, "stmt is null");
932     stmt->SetOpnds(args);
933     return stmt;
934 }
935 
CreateStmtIcallproto(const MapleVector<BaseNode * > & args)936 IcallNode *MIRBuilder::CreateStmtIcallproto(const MapleVector<BaseNode *> &args)
937 {
938     auto *stmt = GetCurrentFuncCodeMp()->New<IcallNode>(*GetCurrentFuncCodeMpAllocator(), OP_icallproto);
939     DEBUG_ASSERT(stmt != nullptr, "stmt is null");
940     stmt->SetOpnds(args);
941     return stmt;
942 }
943 
CreateStmtIcallAssigned(const MapleVector<BaseNode * > & args,const MIRSymbol & ret)944 IcallNode *MIRBuilder::CreateStmtIcallAssigned(const MapleVector<BaseNode *> &args, const MIRSymbol &ret)
945 {
946     auto *stmt = GetCurrentFuncCodeMp()->New<IcallNode>(*GetCurrentFuncCodeMpAllocator(), OP_icallassigned);
947     CallReturnVector nrets(GetCurrentFuncCodeMpAllocator()->Adapter());
948     CHECK_FATAL((ret.GetStorageClass() == kScAuto || ret.GetStorageClass() == kScFormal ||
949                  ret.GetStorageClass() == kScExtern || ret.GetStorageClass() == kScGlobal),
950                 "unknown classtype! check it!");
951     nrets.emplace_back(CallReturnPair(ret.GetStIdx(), RegFieldPair(0, 0)));
952     stmt->SetNumOpnds(args.size());
953     stmt->GetNopnd().resize(stmt->GetNumOpnds());
954     stmt->SetReturnVec(nrets);
955     for (size_t i = 0; i < stmt->GetNopndSize(); ++i) {
956         stmt->SetNOpndAt(i, args.at(i));
957     }
958     stmt->SetRetTyIdx(ret.GetTyIdx());
959     return stmt;
960 }
961 
CreateStmtIcallAssigned(const MapleVector<BaseNode * > & args,PregIdx pregIdx)962 IcallNode *MIRBuilder::CreateStmtIcallAssigned(const MapleVector<BaseNode *> &args, PregIdx pregIdx)
963 {
964     auto *stmt = GetCurrentFuncCodeMp()->New<IcallNode>(*GetCurrentFuncCodeMpAllocator(), OP_icallassigned);
965     CallReturnVector nrets(GetCurrentFuncCodeMpAllocator()->Adapter());
966     nrets.emplace_back(StIdx(), RegFieldPair(0, pregIdx));
967     stmt->SetNumOpnds(args.size());
968     stmt->GetNopnd().resize(stmt->GetNumOpnds());
969     stmt->SetReturnVec(nrets);
970     for (size_t i = 0; i < stmt->GetNopndSize(); ++i) {
971         stmt->SetNOpndAt(i, args.at(i));
972     }
973     auto *preg = GetCurrentFunction()->GetPregTab()->PregFromPregIdx(pregIdx);
974     DEBUG_ASSERT(preg, "preg should be created before used");
975     if (preg->GetMIRType() == nullptr) {
976         stmt->SetRetTyIdx(TyIdx(preg->GetPrimType()));
977     } else {
978         stmt->SetRetTyIdx(preg->GetMIRType()->GetTypeIndex());
979     }
980     return stmt;
981 }
982 
CreateStmtIcallprotoAssigned(const MapleVector<BaseNode * > & args,const MIRSymbol & ret)983 IcallNode *MIRBuilder::CreateStmtIcallprotoAssigned(const MapleVector<BaseNode *> &args, const MIRSymbol &ret)
984 {
985     auto *stmt = GetCurrentFuncCodeMp()->New<IcallNode>(*GetCurrentFuncCodeMpAllocator(), OP_icallprotoassigned);
986     CallReturnVector nrets(GetCurrentFuncCodeMpAllocator()->Adapter());
987     CHECK_FATAL((ret.GetStorageClass() == kScAuto || ret.GetStorageClass() == kScFormal ||
988                  ret.GetStorageClass() == kScExtern || ret.GetStorageClass() == kScGlobal),
989                 "unknown classtype! check it!");
990     nrets.emplace_back(CallReturnPair(ret.GetStIdx(), RegFieldPair(0, 0)));
991     stmt->SetNumOpnds(args.size());
992     stmt->GetNopnd().resize(stmt->GetNumOpnds());
993     stmt->SetReturnVec(nrets);
994     for (size_t i = 0; i < stmt->GetNopndSize(); ++i) {
995         stmt->SetNOpndAt(i, args.at(i));
996     }
997     stmt->SetRetTyIdx(ret.GetTyIdx());
998     return stmt;
999 }
1000 
CreateStmtIntrinsicCall(MIRIntrinsicID idx,const MapleVector<BaseNode * > & arguments,TyIdx tyIdx)1001 IntrinsiccallNode *MIRBuilder::CreateStmtIntrinsicCall(MIRIntrinsicID idx, const MapleVector<BaseNode *> &arguments,
1002                                                        TyIdx tyIdx)
1003 {
1004     auto *stmt = GetCurrentFuncCodeMp()->New<IntrinsiccallNode>(
1005         *GetCurrentFuncCodeMpAllocator(), tyIdx == 0u ? OP_intrinsiccall : OP_intrinsiccallwithtype, idx);
1006     stmt->SetTyIdx(tyIdx);
1007     stmt->SetOpnds(arguments);
1008     return stmt;
1009 }
1010 
CreateStmtXintrinsicCall(MIRIntrinsicID idx,const MapleVector<BaseNode * > & arguments)1011 IntrinsiccallNode *MIRBuilder::CreateStmtXintrinsicCall(MIRIntrinsicID idx, const MapleVector<BaseNode *> &arguments)
1012 {
1013     auto *stmt =
1014         GetCurrentFuncCodeMp()->New<IntrinsiccallNode>(*GetCurrentFuncCodeMpAllocator(), OP_xintrinsiccall, idx);
1015     DEBUG_ASSERT(stmt != nullptr, "stmt is null");
1016     stmt->SetOpnds(arguments);
1017     return stmt;
1018 }
1019 
CreateStmtCallAssigned(PUIdx puIdx,const MIRSymbol * ret,Opcode op)1020 CallNode *MIRBuilder::CreateStmtCallAssigned(PUIdx puIdx, const MIRSymbol *ret, Opcode op)
1021 {
1022     auto *stmt = GetCurrentFuncCodeMp()->New<CallNode>(*GetCurrentFuncCodeMpAllocator(), op, puIdx);
1023     if (ret) {
1024         DEBUG_ASSERT(ret->IsLocal(), "Not Excepted ret");
1025         stmt->GetReturnVec().push_back(CallReturnPair(ret->GetStIdx(), RegFieldPair(0, 0)));
1026     }
1027     return stmt;
1028 }
1029 
CreateStmtCallAssigned(PUIdx puIdx,const MapleVector<BaseNode * > & args,const MIRSymbol * ret,Opcode opcode,TyIdx tyIdx)1030 CallNode *MIRBuilder::CreateStmtCallAssigned(PUIdx puIdx, const MapleVector<BaseNode *> &args, const MIRSymbol *ret,
1031                                              Opcode opcode, TyIdx tyIdx)
1032 {
1033     auto *stmt = GetCurrentFuncCodeMp()->New<CallNode>(*GetCurrentFuncCodeMpAllocator(), opcode, puIdx, tyIdx);
1034     DEBUG_ASSERT(stmt != nullptr, "stmt is null");
1035     stmt->SetOpnds(args);
1036     if (ret != nullptr) {
1037         DEBUG_ASSERT(ret->IsLocal(), "Not Excepted ret");
1038         stmt->GetReturnVec().push_back(CallReturnPair(ret->GetStIdx(), RegFieldPair(0, 0)));
1039     }
1040     return stmt;
1041 }
1042 
CreateStmtCallRegassigned(PUIdx puIdx,PregIdx pRegIdx,Opcode opcode,BaseNode * arg)1043 CallNode *MIRBuilder::CreateStmtCallRegassigned(PUIdx puIdx, PregIdx pRegIdx, Opcode opcode, BaseNode *arg)
1044 {
1045     auto *stmt = GetCurrentFuncCodeMp()->New<CallNode>(*GetCurrentFuncCodeMpAllocator(), opcode, puIdx);
1046     stmt->GetNopnd().push_back(arg);
1047     stmt->SetNumOpnds(stmt->GetNopndSize());
1048     if (pRegIdx > 0) {
1049         stmt->GetReturnVec().push_back(CallReturnPair(StIdx(), RegFieldPair(0, pRegIdx)));
1050     }
1051     return stmt;
1052 }
1053 
CreateStmtCallRegassigned(PUIdx puIdx,const MapleVector<BaseNode * > & args,PregIdx pRegIdx,Opcode opcode)1054 CallNode *MIRBuilder::CreateStmtCallRegassigned(PUIdx puIdx, const MapleVector<BaseNode *> &args, PregIdx pRegIdx,
1055                                                 Opcode opcode)
1056 {
1057     auto *stmt = GetCurrentFuncCodeMp()->New<CallNode>(*GetCurrentFuncCodeMpAllocator(), opcode, puIdx);
1058     DEBUG_ASSERT(stmt != nullptr, "stmt is null");
1059     stmt->SetOpnds(args);
1060     if (pRegIdx > 0) {
1061         stmt->GetReturnVec().push_back(CallReturnPair(StIdx(), RegFieldPair(0, pRegIdx)));
1062     }
1063     return stmt;
1064 }
1065 
CreateStmtIntrinsicCallAssigned(MIRIntrinsicID idx,const MapleVector<BaseNode * > & args,PregIdx retPregIdx)1066 IntrinsiccallNode *MIRBuilder::CreateStmtIntrinsicCallAssigned(MIRIntrinsicID idx, const MapleVector<BaseNode *> &args,
1067                                                                PregIdx retPregIdx)
1068 {
1069     auto *stmt =
1070         GetCurrentFuncCodeMp()->New<IntrinsiccallNode>(*GetCurrentFuncCodeMpAllocator(), OP_intrinsiccallassigned, idx);
1071     DEBUG_ASSERT(stmt != nullptr, "stmt is null");
1072     stmt->SetOpnds(args);
1073     if (retPregIdx > 0) {
1074         stmt->GetReturnVec().push_back(CallReturnPair(StIdx(), RegFieldPair(0, retPregIdx)));
1075     }
1076     return stmt;
1077 }
1078 
CreateStmtIntrinsicCallAssigned(MIRIntrinsicID idx,const MapleVector<BaseNode * > & args,const MIRSymbol * ret,TyIdx tyIdx)1079 IntrinsiccallNode *MIRBuilder::CreateStmtIntrinsicCallAssigned(MIRIntrinsicID idx, const MapleVector<BaseNode *> &args,
1080                                                                const MIRSymbol *ret, TyIdx tyIdx)
1081 {
1082     auto *stmt = GetCurrentFuncCodeMp()->New<IntrinsiccallNode>(
1083         *GetCurrentFuncCodeMpAllocator(), tyIdx == 0u ? OP_intrinsiccallassigned : OP_intrinsiccallwithtypeassigned,
1084         idx);
1085     stmt->SetTyIdx(tyIdx);
1086     stmt->SetOpnds(args);
1087     CallReturnVector nrets(GetCurrentFuncCodeMpAllocator()->Adapter());
1088     if (ret != nullptr) {
1089         DEBUG_ASSERT(ret->IsLocal(), "Not Excepted ret");
1090         nrets.push_back(CallReturnPair(ret->GetStIdx(), RegFieldPair(0, 0)));
1091     }
1092     stmt->SetReturnVec(nrets);
1093     return stmt;
1094 }
1095 
CreateStmtXintrinsicCallAssigned(MIRIntrinsicID idx,const MapleVector<BaseNode * > & args,const MIRSymbol * ret)1096 IntrinsiccallNode *MIRBuilder::CreateStmtXintrinsicCallAssigned(MIRIntrinsicID idx, const MapleVector<BaseNode *> &args,
1097                                                                 const MIRSymbol *ret)
1098 {
1099     auto *stmt = GetCurrentFuncCodeMp()->New<IntrinsiccallNode>(*GetCurrentFuncCodeMpAllocator(),
1100                                                                 OP_xintrinsiccallassigned, idx);
1101     DEBUG_ASSERT(stmt != nullptr, "stmt is null");
1102     stmt->SetOpnds(args);
1103     CallReturnVector nrets(GetCurrentFuncCodeMpAllocator()->Adapter());
1104     if (ret != nullptr) {
1105         DEBUG_ASSERT(ret->IsLocal(), "Not Excepted ret");
1106         nrets.push_back(CallReturnPair(ret->GetStIdx(), RegFieldPair(0, 0)));
1107     }
1108     stmt->SetReturnVec(nrets);
1109     return stmt;
1110 }
1111 
CreateStmtReturn(BaseNode * rVal)1112 NaryStmtNode *MIRBuilder::CreateStmtReturn(BaseNode *rVal)
1113 {
1114     auto *stmt = GetCurrentFuncCodeMp()->New<NaryStmtNode>(*GetCurrentFuncCodeMpAllocator(), OP_return);
1115     DEBUG_ASSERT(stmt != nullptr, "stmt is null");
1116     stmt->PushOpnd(rVal);
1117     return stmt;
1118 }
1119 
CreateStmtNary(Opcode op,const MapleVector<BaseNode * > & rVals)1120 NaryStmtNode *MIRBuilder::CreateStmtNary(Opcode op, const MapleVector<BaseNode *> &rVals)
1121 {
1122     auto *stmt = GetCurrentFuncCodeMp()->New<NaryStmtNode>(*GetCurrentFuncCodeMpAllocator(), op);
1123     DEBUG_ASSERT(stmt != nullptr, "stmt is null");
1124     stmt->SetOpnds(rVals);
1125     return stmt;
1126 }
1127 
CreateStmtCallAssertBoundary(Opcode op,const MapleVector<BaseNode * > & rVals,GStrIdx funcNameIdx,size_t paramIndex,GStrIdx stmtFuncNameIdx)1128 CallAssertBoundaryStmtNode *MIRBuilder::CreateStmtCallAssertBoundary(Opcode op, const MapleVector<BaseNode *> &rVals,
1129                                                                      GStrIdx funcNameIdx, size_t paramIndex,
1130                                                                      GStrIdx stmtFuncNameIdx)
1131 {
1132     auto *stmt = GetCurrentFuncCodeMp()->New<CallAssertBoundaryStmtNode>(*GetCurrentFuncCodeMpAllocator(), op,
1133                                                                          funcNameIdx, paramIndex, stmtFuncNameIdx);
1134     DEBUG_ASSERT(stmt != nullptr, "stmt is null");
1135     stmt->SetOpnds(rVals);
1136     return stmt;
1137 }
1138 
CreateStmtNary(Opcode op,BaseNode * rVal)1139 NaryStmtNode *MIRBuilder::CreateStmtNary(Opcode op, BaseNode *rVal)
1140 {
1141     auto *stmt = GetCurrentFuncCodeMp()->New<NaryStmtNode>(*GetCurrentFuncCodeMpAllocator(), op);
1142     DEBUG_ASSERT(stmt != nullptr, "stmt is null");
1143     stmt->PushOpnd(rVal);
1144     return stmt;
1145 }
1146 
CreateStmtAssertNonnull(Opcode op,BaseNode * rVal,GStrIdx funcNameIdx)1147 AssertNonnullStmtNode *MIRBuilder::CreateStmtAssertNonnull(Opcode op, BaseNode *rVal, GStrIdx funcNameIdx)
1148 {
1149     auto *stmt = GetCurrentFuncCodeMp()->New<AssertNonnullStmtNode>(op, funcNameIdx);
1150     DEBUG_ASSERT(stmt != nullptr, "stmt is null");
1151     stmt->SetRHS(rVal);
1152     return stmt;
1153 }
1154 
CreateStmtAssertBoundary(Opcode op,const MapleVector<BaseNode * > & rVals,GStrIdx funcNameIdx)1155 AssertBoundaryStmtNode *MIRBuilder::CreateStmtAssertBoundary(Opcode op, const MapleVector<BaseNode *> &rVals,
1156                                                              GStrIdx funcNameIdx)
1157 {
1158     auto *stmt = GetCurrentFuncCodeMp()->New<AssertBoundaryStmtNode>(*GetCurrentFuncCodeMpAllocator(), op, funcNameIdx);
1159     DEBUG_ASSERT(stmt != nullptr, "stmt is null");
1160     stmt->SetOpnds(rVals);
1161     return stmt;
1162 }
1163 
CreateStmtCallAssertNonnull(Opcode op,BaseNode * rVal,GStrIdx callFuncNameIdx,size_t paramIndex,GStrIdx stmtFuncNameIdx)1164 CallAssertNonnullStmtNode *MIRBuilder::CreateStmtCallAssertNonnull(Opcode op, BaseNode *rVal, GStrIdx callFuncNameIdx,
1165                                                                    size_t paramIndex, GStrIdx stmtFuncNameIdx)
1166 {
1167     auto *stmt =
1168         GetCurrentFuncCodeMp()->New<CallAssertNonnullStmtNode>(op, callFuncNameIdx, paramIndex, stmtFuncNameIdx);
1169     DEBUG_ASSERT(stmt != nullptr, "stmt is null");
1170     stmt->SetRHS(rVal);
1171     return stmt;
1172 }
1173 
CreateStmtUnary(Opcode op,BaseNode * rVal)1174 UnaryStmtNode *MIRBuilder::CreateStmtUnary(Opcode op, BaseNode *rVal)
1175 {
1176     return GetCurrentFuncCodeMp()->New<UnaryStmtNode>(op, kPtyInvalid, rVal);
1177 }
1178 
CreateStmtThrow(BaseNode * rVal)1179 UnaryStmtNode *MIRBuilder::CreateStmtThrow(BaseNode *rVal)
1180 {
1181     return CreateStmtUnary(OP_throw, rVal);
1182 }
1183 
CreateStmtIf(BaseNode * cond)1184 IfStmtNode *MIRBuilder::CreateStmtIf(BaseNode *cond)
1185 {
1186     auto *ifStmt = GetCurrentFuncCodeMp()->New<IfStmtNode>();
1187     ifStmt->SetOpnd(cond, 0);
1188     BlockNode *thenBlock = GetCurrentFuncCodeMp()->New<BlockNode>();
1189     ifStmt->SetThenPart(thenBlock);
1190     return ifStmt;
1191 }
1192 
CreateStmtIfThenElse(BaseNode * cond)1193 IfStmtNode *MIRBuilder::CreateStmtIfThenElse(BaseNode *cond)
1194 {
1195     auto *ifStmt = GetCurrentFuncCodeMp()->New<IfStmtNode>();
1196     ifStmt->SetOpnd(cond, 0);
1197     auto *thenBlock = GetCurrentFuncCodeMp()->New<BlockNode>();
1198     ifStmt->SetThenPart(thenBlock);
1199     auto *elseBlock = GetCurrentFuncCodeMp()->New<BlockNode>();
1200     ifStmt->SetElsePart(elseBlock);
1201     ifStmt->SetNumOpnds(3); // 3 operands
1202     return ifStmt;
1203 }
1204 
CreateStmtDoloop(StIdx doVarStIdx,bool isPReg,BaseNode * startExp,BaseNode * contExp,BaseNode * incrExp)1205 DoloopNode *MIRBuilder::CreateStmtDoloop(StIdx doVarStIdx, bool isPReg, BaseNode *startExp, BaseNode *contExp,
1206                                          BaseNode *incrExp)
1207 {
1208     return GetCurrentFuncCodeMp()->New<DoloopNode>(doVarStIdx, isPReg, startExp, contExp, incrExp,
1209                                                    GetCurrentFuncCodeMp()->New<BlockNode>());
1210 }
1211 
CreateStmtSwitch(BaseNode * opnd,LabelIdx defaultLabel,const CaseVector & switchTable)1212 SwitchNode *MIRBuilder::CreateStmtSwitch(BaseNode *opnd, LabelIdx defaultLabel, const CaseVector &switchTable)
1213 {
1214     auto *switchNode = GetCurrentFuncCodeMp()->New<SwitchNode>(*GetCurrentFuncCodeMpAllocator(), defaultLabel, opnd);
1215     switchNode->SetSwitchTable(switchTable);
1216     return switchNode;
1217 }
1218 
CreateStmtGoto(Opcode o,LabelIdx labIdx)1219 GotoNode *MIRBuilder::CreateStmtGoto(Opcode o, LabelIdx labIdx)
1220 {
1221     return GetCurrentFuncCodeMp()->New<GotoNode>(o, labIdx);
1222 }
1223 
CreateStmtJsTry(Opcode,LabelIdx cLabIdx,LabelIdx fLabIdx)1224 JsTryNode *MIRBuilder::CreateStmtJsTry(Opcode, LabelIdx cLabIdx, LabelIdx fLabIdx)
1225 {
1226     return GetCurrentFuncCodeMp()->New<JsTryNode>(static_cast<uint16>(cLabIdx), static_cast<uint16>(fLabIdx));
1227 }
1228 
CreateStmtTry(const MapleVector<LabelIdx> & cLabIdxs)1229 TryNode *MIRBuilder::CreateStmtTry(const MapleVector<LabelIdx> &cLabIdxs)
1230 {
1231     return GetCurrentFuncCodeMp()->New<TryNode>(cLabIdxs);
1232 }
1233 
CreateStmtCatch(const MapleVector<TyIdx> & tyIdxVec)1234 CatchNode *MIRBuilder::CreateStmtCatch(const MapleVector<TyIdx> &tyIdxVec)
1235 {
1236     return GetCurrentFuncCodeMp()->New<CatchNode>(tyIdxVec);
1237 }
1238 
CreateStmtLabel(LabelIdx labIdx)1239 LabelNode *MIRBuilder::CreateStmtLabel(LabelIdx labIdx)
1240 {
1241     return GetCurrentFuncCodeMp()->New<LabelNode>(labIdx);
1242 }
1243 
CreateStmtComment(const std::string & cmnt)1244 StmtNode *MIRBuilder::CreateStmtComment(const std::string &cmnt)
1245 {
1246     return GetCurrentFuncCodeMp()->New<CommentNode>(*GetCurrentFuncCodeMpAllocator(), cmnt);
1247 }
1248 
CreateAddrof(const MIRSymbol & st,PrimType pty)1249 AddrofNode *MIRBuilder::CreateAddrof(const MIRSymbol &st, PrimType pty)
1250 {
1251     return GetCurrentFuncCodeMp()->New<AddrofNode>(OP_addrof, pty, st.GetStIdx(), 0);
1252 }
1253 
CreateDread(const MIRSymbol & st,PrimType pty)1254 AddrofNode *MIRBuilder::CreateDread(const MIRSymbol &st, PrimType pty)
1255 {
1256     return GetCurrentFuncCodeMp()->New<AddrofNode>(OP_dread, pty, st.GetStIdx(), 0);
1257 }
1258 
CreateStmtCondGoto(BaseNode * cond,Opcode op,LabelIdx labIdx)1259 CondGotoNode *MIRBuilder::CreateStmtCondGoto(BaseNode *cond, Opcode op, LabelIdx labIdx)
1260 {
1261     return GetCurrentFuncCodeMp()->New<CondGotoNode>(op, labIdx, cond);
1262 }
1263 
GetOrCreateMIRLabel(const std::string & name)1264 LabelIdx MIRBuilder::GetOrCreateMIRLabel(const std::string &name)
1265 {
1266     GStrIdx strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(name);
1267     MIRFunction *currentFunctionInner = GetCurrentFunctionNotNull();
1268     LabelIdx lableIdx = currentFunctionInner->GetLabelTab()->GetLabelIdxFromStrIdx(strIdx);
1269     if (lableIdx == 0) {
1270         lableIdx = currentFunctionInner->GetLabelTab()->CreateLabel();
1271         currentFunctionInner->GetLabelTab()->SetSymbolFromStIdx(lableIdx, strIdx);
1272         currentFunctionInner->GetLabelTab()->AddToStringLabelMap(lableIdx);
1273     }
1274     return lableIdx;
1275 }
1276 
CreateLabIdx(MIRFunction & mirFunc)1277 LabelIdx MIRBuilder::CreateLabIdx(MIRFunction &mirFunc)
1278 {
1279     LabelIdx lableIdx = mirFunc.GetLabelTab()->CreateLabel();
1280     mirFunc.GetLabelTab()->AddToStringLabelMap(lableIdx);
1281     return lableIdx;
1282 }
1283 
AddStmtInCurrentFunctionBody(StmtNode & stmt)1284 void MIRBuilder::AddStmtInCurrentFunctionBody(StmtNode &stmt)
1285 {
1286     MIRFunction *fun = GetCurrentFunctionNotNull();
1287     stmt.GetSrcPos().CondSetLineNum(lineNum);
1288     fun->GetBody()->AddStatement(&stmt);
1289 }
1290 
GetCurrentFuncCodeMp()1291 MemPool *MIRBuilder::GetCurrentFuncCodeMp()
1292 {
1293     if (MIRFunction *curFunction = GetCurrentFunction()) {
1294         return curFunction->GetCodeMemPool();
1295     }
1296     return mirModule->GetMemPool();
1297 }
1298 
GetCurrentFuncCodeMpAllocator()1299 MapleAllocator *MIRBuilder::GetCurrentFuncCodeMpAllocator()
1300 {
1301     if (MIRFunction *curFunction = GetCurrentFunction()) {
1302         return &curFunction->GetCodeMPAllocator();
1303     }
1304     return &mirModule->GetMPAllocator();
1305 }
1306 
GetCurrentFuncDataMp()1307 MemPool *MIRBuilder::GetCurrentFuncDataMp()
1308 {
1309     if (MIRFunction *curFunction = GetCurrentFunction()) {
1310         return curFunction->GetDataMemPool();
1311     }
1312     return mirModule->GetMemPool();
1313 }
1314 
MIRBuilderExt(MIRModule * module,pthread_mutex_t * mutex)1315 MIRBuilderExt::MIRBuilderExt(MIRModule *module, pthread_mutex_t *mutex) : MIRBuilder(module), mutex(mutex) {}
1316 
GetCurrentFuncCodeMp()1317 MemPool *MIRBuilderExt::GetCurrentFuncCodeMp()
1318 {
1319     DEBUG_ASSERT(curFunction, "curFunction is null");
1320     return curFunction->GetCodeMemPool();
1321 }
1322 
GetCurrentFuncCodeMpAllocator()1323 MapleAllocator *MIRBuilderExt::GetCurrentFuncCodeMpAllocator()
1324 {
1325     DEBUG_ASSERT(curFunction, "curFunction is null");
1326     return &curFunction->GetCodeMemPoolAllocator();
1327 }
1328 
GlobalLock()1329 void MIRBuilderExt::GlobalLock()
1330 {
1331     if (mutex) {
1332         DEBUG_ASSERT(pthread_mutex_lock(mutex) == 0, "lock failed");
1333     }
1334 }
1335 
GlobalUnlock()1336 void MIRBuilderExt::GlobalUnlock()
1337 {
1338     if (mutex) {
1339         DEBUG_ASSERT(pthread_mutex_unlock(mutex) == 0, "unlock failed");
1340     }
1341 }
1342 }  // namespace maple
1343