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