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