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