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 // create a function named str
GetOrCreateFunction(const std::string & str,TyIdx retTyIdx)21 MIRFunction *MIRBuilder::GetOrCreateFunction(const std::string &str, TyIdx retTyIdx)
22 {
23 GStrIdx strIdx = GetStringIndex(str);
24 MIRSymbol *funcSt = nullptr;
25 if (strIdx != 0u) {
26 funcSt = GlobalTables::GetGsymTable().GetSymbolFromStrIdx(strIdx);
27 if (funcSt == nullptr) {
28 funcSt = CreateSymbol(TyIdx(0), strIdx, kStFunc, kScText, nullptr, kScopeGlobal);
29 } else {
30 DEBUG_ASSERT(funcSt->GetSKind() == kStFunc, "runtime check error");
31 return funcSt->GetFunction();
32 }
33 } else {
34 strIdx = GetOrCreateStringIndex(str);
35 funcSt = CreateSymbol(TyIdx(0), strIdx, kStFunc, kScText, nullptr, kScopeGlobal);
36 }
37 auto *fn = mirModule->GetMemPool()->New<MIRFunction>(mirModule, funcSt->GetStIdx());
38 fn->SetPuidx(GlobalTables::GetFunctionTable().GetFuncTable().size());
39 MIRFuncType funcType;
40 funcType.SetRetTyIdx(retTyIdx);
41 auto funcTyIdx = GlobalTables::GetTypeTable().GetOrCreateMIRType(&funcType);
42 auto *funcTypeInTypeTable = static_cast<MIRFuncType *>(GlobalTables::GetTypeTable().GetTypeFromTyIdx(funcTyIdx));
43 fn->SetMIRFuncType(funcTypeInTypeTable);
44 fn->SetReturnTyIdx(retTyIdx);
45 GlobalTables::GetFunctionTable().GetFuncTable().push_back(fn);
46 funcSt->SetFunction(fn);
47 funcSt->SetTyIdx(funcTyIdx);
48 return fn;
49 }
50
GetFunctionFromSymbol(const MIRSymbol & funcSymbol)51 MIRFunction *MIRBuilder::GetFunctionFromSymbol(const MIRSymbol &funcSymbol)
52 {
53 DEBUG_ASSERT(funcSymbol.GetSKind() == kStFunc, "Symbol %s is not a function symbol", funcSymbol.GetName().c_str());
54 return funcSymbol.GetFunction();
55 }
56
GetFunctionFromName(const std::string & str)57 MIRFunction *MIRBuilder::GetFunctionFromName(const std::string &str)
58 {
59 auto *funcSymbol =
60 GlobalTables::GetGsymTable().GetSymbolFromStrIdx(GlobalTables::GetStrTable().GetStrIdxFromName(str));
61 return funcSymbol != nullptr ? GetFunctionFromSymbol(*funcSymbol) : nullptr;
62 }
63
CreateFunction(const std::string & name,const MIRType & returnType,const ArgVector & arguments,bool isVarg,bool createBody) const64 MIRFunction *MIRBuilder::CreateFunction(const std::string &name, const MIRType &returnType, const ArgVector &arguments,
65 bool isVarg, bool createBody) const
66 {
67 MIRSymbol *funcSymbol = GlobalTables::GetGsymTable().CreateSymbol(kScopeGlobal);
68 GStrIdx strIdx = GetOrCreateStringIndex(name);
69 funcSymbol->SetNameStrIdx(strIdx);
70 if (!GlobalTables::GetGsymTable().AddToStringSymbolMap(*funcSymbol)) {
71 return nullptr;
72 }
73 funcSymbol->SetStorageClass(kScText);
74 funcSymbol->SetSKind(kStFunc);
75 auto *fn = mirModule->GetMemPool()->New<MIRFunction>(mirModule, funcSymbol->GetStIdx());
76 fn->SetPuidx(GlobalTables::GetFunctionTable().GetFuncTable().size());
77 GlobalTables::GetFunctionTable().GetFuncTable().push_back(fn);
78 std::vector<TyIdx> funcVecType;
79 std::vector<TypeAttrs> funcVecAttrs;
80 for (size_t i = 0; i < arguments.size(); ++i) {
81 MIRType *ty = arguments[i].second;
82 FormalDef formalDef(GetOrCreateStringIndex(arguments[i].first.c_str()), nullptr, ty->GetTypeIndex(),
83 TypeAttrs());
84 fn->GetFormalDefVec().push_back(formalDef);
85 funcVecType.push_back(ty->GetTypeIndex());
86 funcVecAttrs.push_back(TypeAttrs());
87 if (fn->GetSymTab() != nullptr && formalDef.formalSym != nullptr) {
88 (void)fn->GetSymTab()->AddToStringSymbolMap(*formalDef.formalSym);
89 }
90 }
91 funcSymbol->SetTyIdx(GlobalTables::GetTypeTable()
92 .GetOrCreateFunctionType(returnType.GetTypeIndex(), funcVecType, funcVecAttrs, isVarg)
93 ->GetTypeIndex());
94 auto *funcType = static_cast<MIRFuncType *>(funcSymbol->GetType());
95 fn->SetMIRFuncType(funcType);
96 funcSymbol->SetFunction(fn);
97 if (createBody) {
98 fn->NewBody();
99 }
100 return fn;
101 }
102
GetOrCreateLocalDecl(const std::string & str,TyIdx tyIdx,MIRSymbolTable & symbolTable,bool & created) const103 MIRSymbol *MIRBuilder::GetOrCreateLocalDecl(const std::string &str, TyIdx tyIdx, MIRSymbolTable &symbolTable,
104 bool &created) const
105 {
106 GStrIdx strIdx = GetStringIndex(str);
107 if (strIdx != 0u) {
108 StIdx stIdx = symbolTable.GetStIdxFromStrIdx(strIdx);
109 if (stIdx.Idx() != 0) {
110 created = false;
111 return symbolTable.GetSymbolFromStIdx(stIdx.Idx());
112 }
113 }
114 created = true;
115 strIdx = GetOrCreateStringIndex(str);
116 MIRSymbol *st = symbolTable.CreateSymbol(kScopeLocal);
117 DEBUG_ASSERT(st != nullptr, "null ptr check");
118 st->SetNameStrIdx(strIdx);
119 st->SetTyIdx(tyIdx);
120 (void)symbolTable.AddToStringSymbolMap(*st);
121 return st;
122 }
123
GetOrCreateDeclInFunc(const std::string & str,const MIRType & type,MIRFunction & func)124 MIRSymbol *MIRBuilder::GetOrCreateDeclInFunc(const std::string &str, const MIRType &type, MIRFunction &func)
125 {
126 MIRSymbolTable *symbolTable = func.GetSymTab();
127 DEBUG_ASSERT(symbolTable != nullptr, "symbol_table is null");
128 bool isCreated = false;
129 MIRSymbol *st = GetOrCreateLocalDecl(str, type.GetTypeIndex(), *symbolTable, isCreated);
130 DEBUG_ASSERT(st != nullptr, "st is null");
131 if (isCreated) {
132 st->SetStorageClass(kScAuto);
133 st->SetSKind(kStVar);
134 }
135 return st;
136 }
137
GetOrCreateLocalDecl(const std::string & str,const MIRType & type)138 MIRSymbol *MIRBuilder::GetOrCreateLocalDecl(const std::string &str, const MIRType &type)
139 {
140 MIRFunction *currentFunc = GetCurrentFunction();
141 CHECK_FATAL(currentFunc != nullptr, "null ptr check");
142 return GetOrCreateDeclInFunc(str, type, *currentFunc);
143 }
144
GetLocalDecl(const std::string & str)145 MIRSymbol *MIRBuilder::GetLocalDecl(const std::string &str)
146 {
147 MIRFunction *currentFunctionInner = GetCurrentFunctionNotNull();
148 return MIRSymbolBuilder::Instance().GetLocalDecl(*currentFunctionInner->GetSymTab(), GetStringIndex(str));
149 }
150
151 // 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) const152 MIRSymbol *MIRBuilder::CreateSymbol(TyIdx tyIdx, const std::string &name, MIRSymKind mClass, MIRStorageClass sClass,
153 MIRFunction *func, uint8 scpID) const
154 {
155 return CreateSymbol(tyIdx, GetOrCreateStringIndex(name), mClass, sClass, func, scpID);
156 }
157
158 // when func is null, create global symbol, otherwise create local symbol
CreateSymbol(TyIdx tyIdx,GStrIdx strIdx,MIRSymKind mClass,MIRStorageClass sClass,MIRFunction * func,uint8 scpID) const159 MIRSymbol *MIRBuilder::CreateSymbol(TyIdx tyIdx, GStrIdx strIdx, MIRSymKind mClass, MIRStorageClass sClass,
160 MIRFunction *func, uint8 scpID) const
161 {
162 return MIRSymbolBuilder::Instance().CreateSymbol(tyIdx, strIdx, mClass, sClass, func, scpID);
163 }
164
CreatePregFormalSymbol(TyIdx tyIdx,PregIdx pRegIdx,MIRFunction & func) const165 MIRSymbol *MIRBuilder::CreatePregFormalSymbol(TyIdx tyIdx, PregIdx pRegIdx, MIRFunction &func) const
166 {
167 return MIRSymbolBuilder::Instance().CreatePregFormalSymbol(tyIdx, pRegIdx, func);
168 }
169
CreateConstval(MIRConst * mirConst)170 ConstvalNode *MIRBuilder::CreateConstval(MIRConst *mirConst)
171 {
172 return NewNode<ConstvalNode>(mirConst->GetType().GetPrimType(), mirConst);
173 }
174
CreateIntConst(uint64 val,PrimType pty)175 ConstvalNode *MIRBuilder::CreateIntConst(uint64 val, PrimType pty)
176 {
177 auto *mirConst =
178 GlobalTables::GetIntConstTable().GetOrCreateIntConst(val, *GlobalTables::GetTypeTable().GetPrimType(pty));
179 return NewNode<ConstvalNode>(pty, mirConst);
180 }
181
CreateExprAddrof(FieldID fieldID,const MIRSymbol & symbol,MemPool * memPool)182 AddrofNode *MIRBuilder::CreateExprAddrof(FieldID fieldID, const MIRSymbol &symbol, MemPool *memPool)
183 {
184 return CreateExprAddrof(fieldID, symbol.GetStIdx(), memPool);
185 }
186
CreateExprAddrof(FieldID fieldID,StIdx symbolStIdx,MemPool * memPool)187 AddrofNode *MIRBuilder::CreateExprAddrof(FieldID fieldID, StIdx symbolStIdx, MemPool *memPool)
188 {
189 if (memPool == nullptr) {
190 memPool = GetCurrentFuncCodeMp();
191 }
192 auto node = memPool->New<AddrofNode>(OP_addrof, PTY_ptr, symbolStIdx, fieldID);
193 node->SetDebugComment(currComment);
194 return node;
195 }
196
CreateExprDread(const MIRType & type,FieldID fieldID,const MIRSymbol & symbol)197 AddrofNode *MIRBuilder::CreateExprDread(const MIRType &type, FieldID fieldID, const MIRSymbol &symbol)
198 {
199 return CreateExprDread(type.GetPrimType(), fieldID, symbol);
200 }
201
CreateExprDread(PrimType ptyp,FieldID fieldID,const MIRSymbol & symbol)202 AddrofNode *MIRBuilder::CreateExprDread(PrimType ptyp, FieldID fieldID, const MIRSymbol &symbol)
203 {
204 auto *node = NewNode<AddrofNode>(OP_dread, kPtyInvalid, symbol.GetStIdx(), fieldID);
205 node->SetPrimType(GetRegPrimType(ptyp));
206 return node;
207 }
208
CreateExprRegread(PrimType pty,PregIdx regIdx)209 RegreadNode *MIRBuilder::CreateExprRegread(PrimType pty, PregIdx regIdx)
210 {
211 return NewNode<RegreadNode>(pty, regIdx);
212 }
213
214
CreateExprDread(MIRSymbol & symbol)215 AddrofNode *MIRBuilder::CreateExprDread(MIRSymbol &symbol)
216 {
217 return CreateExprDread(*symbol.GetType(), 0, symbol);
218 }
219
CreateExprIread(const MIRType & returnType,const MIRType & ptrType,FieldID fieldID,BaseNode * addr)220 IreadNode *MIRBuilder::CreateExprIread(const MIRType &returnType, const MIRType &ptrType, FieldID fieldID,
221 BaseNode *addr)
222 {
223 TyIdx returnTypeIdx = returnType.GetTypeIndex();
224 CHECK(returnTypeIdx < GlobalTables::GetTypeTable().GetTypeTable().size(),
225 "index out of range in MIRBuilder::CreateExprIread");
226 PrimType type = GetRegPrimType(returnType.GetPrimType());
227 return NewNode<IreadNode>(OP_iread, type, ptrType.GetTypeIndex(), fieldID, addr);
228 }
229
CreateExprUnary(Opcode opcode,const MIRType & type,BaseNode * opnd)230 UnaryNode *MIRBuilder::CreateExprUnary(Opcode opcode, const MIRType &type, BaseNode *opnd)
231 {
232 return NewNode<UnaryNode>(opcode, type.GetPrimType(), opnd);
233 }
234
CreateExprTypeCvt(Opcode o,PrimType toPrimType,PrimType fromPrimType,BaseNode & opnd)235 TypeCvtNode *MIRBuilder::CreateExprTypeCvt(Opcode o, PrimType toPrimType, PrimType fromPrimType, BaseNode &opnd)
236 {
237 return NewNode<TypeCvtNode>(o, toPrimType, fromPrimType, &opnd);
238 }
239
CreateExprTypeCvt(Opcode o,const MIRType & type,const MIRType & fromType,BaseNode * opnd)240 TypeCvtNode *MIRBuilder::CreateExprTypeCvt(Opcode o, const MIRType &type, const MIRType &fromType, BaseNode *opnd)
241 {
242 return CreateExprTypeCvt(o, type.GetPrimType(), fromType.GetPrimType(), *opnd);
243 }
244
CreateExprExtractbits(Opcode o,PrimType type,uint32 bOffset,uint32 bSize,BaseNode * opnd)245 ExtractbitsNode *MIRBuilder::CreateExprExtractbits(Opcode o, PrimType type, uint32 bOffset, uint32 bSize,
246 BaseNode *opnd)
247 {
248 return NewNode<ExtractbitsNode>(o, type, bOffset, bSize, opnd);
249 }
250
CreateExprRetype(const MIRType & type,const MIRType & fromType,BaseNode * opnd)251 RetypeNode *MIRBuilder::CreateExprRetype(const MIRType &type, const MIRType &fromType, BaseNode *opnd)
252 {
253 return CreateExprRetype(type, fromType.GetPrimType(), opnd);
254 }
255
CreateExprRetype(const MIRType & type,PrimType fromType,BaseNode * opnd)256 RetypeNode *MIRBuilder::CreateExprRetype(const MIRType &type, PrimType fromType, BaseNode *opnd)
257 {
258 return NewNode<RetypeNode>(type.GetPrimType(), fromType, type.GetTypeIndex(), opnd);
259 }
260
CreateExprBinary(Opcode opcode,const MIRType & type,BaseNode * opnd0,BaseNode * opnd1)261 BinaryNode *MIRBuilder::CreateExprBinary(Opcode opcode, const MIRType &type, BaseNode *opnd0, BaseNode *opnd1)
262 {
263 return NewNode<BinaryNode>(opcode, type.GetPrimType(), opnd0, opnd1);
264 }
265
CreateExprCompare(Opcode opcode,const MIRType & type,const MIRType & opndType,BaseNode * opnd0,BaseNode * opnd1)266 CompareNode *MIRBuilder::CreateExprCompare(Opcode opcode, const MIRType &type, const MIRType &opndType, BaseNode *opnd0,
267 BaseNode *opnd1)
268 {
269 return NewNode<CompareNode>(opcode, type.GetPrimType(), opndType.GetPrimType(), opnd0, opnd1);
270 }
271
CreateExprIntrinsicop(MIRIntrinsicID id,Opcode op,PrimType primType,TyIdx tyIdx,const MapleVector<BaseNode * > & ops)272 IntrinsicopNode *MIRBuilder::CreateExprIntrinsicop(MIRIntrinsicID id, Opcode op, PrimType primType, TyIdx tyIdx,
273 const MapleVector<BaseNode *> &ops)
274 {
275 auto *expr = NewNode<IntrinsicopNode>(*GetCurrentFuncCodeMpAllocator(), op, primType);
276 expr->SetIntrinsic(id);
277 expr->SetNOpnd(ops);
278 expr->SetNumOpnds(ops.size());
279 return expr;
280 }
281
CreateExprIntrinsicop(MIRIntrinsicID idx,Opcode opCode,const MIRType & type,const MapleVector<BaseNode * > & ops)282 IntrinsicopNode *MIRBuilder::CreateExprIntrinsicop(MIRIntrinsicID idx, Opcode opCode, const MIRType &type,
283 const MapleVector<BaseNode *> &ops)
284 {
285 return CreateExprIntrinsicop(idx, opCode, type.GetPrimType(), type.GetTypeIndex(), ops);
286 }
287
CreateStmtDassign(const MIRSymbol & symbol,FieldID fieldID,BaseNode * src)288 DassignNode *MIRBuilder::CreateStmtDassign(const MIRSymbol &symbol, FieldID fieldID, BaseNode *src)
289 {
290 return NewNode<DassignNode>(src, symbol.GetStIdx(), fieldID);
291 }
292
CreateStmtRegassign(PrimType pty,PregIdx regIdx,BaseNode * src)293 RegassignNode *MIRBuilder::CreateStmtRegassign(PrimType pty, PregIdx regIdx, BaseNode *src)
294 {
295 return NewNode<RegassignNode>(pty, regIdx, src);
296 }
297
CreateStmtDassign(StIdx sIdx,FieldID fieldID,BaseNode * src)298 DassignNode *MIRBuilder::CreateStmtDassign(StIdx sIdx, FieldID fieldID, BaseNode *src)
299 {
300 return NewNode<DassignNode>(src, sIdx, fieldID);
301 }
302
CreateStmtIassign(const MIRType & type,FieldID fieldID,BaseNode * addr,BaseNode * src)303 IassignNode *MIRBuilder::CreateStmtIassign(const MIRType &type, FieldID fieldID, BaseNode *addr, BaseNode *src)
304 {
305 return NewNode<IassignNode>(type.GetTypeIndex(), fieldID, addr, src);
306 }
307
CreateStmtCall(PUIdx puIdx,const MapleVector<BaseNode * > & args,Opcode opCode)308 CallNode *MIRBuilder::CreateStmtCall(PUIdx puIdx, const MapleVector<BaseNode *> &args, Opcode opCode)
309 {
310 auto *stmt = NewNode<CallNode>(*GetCurrentFuncCodeMpAllocator(), opCode, puIdx, TyIdx());
311 stmt->SetNOpnd(args);
312 stmt->SetNumOpnds(args.size());
313 return stmt;
314 }
315
CreateStmtIcall(const MapleVector<BaseNode * > & args)316 IcallNode *MIRBuilder::CreateStmtIcall(const MapleVector<BaseNode *> &args)
317 {
318 auto *stmt = NewNode<IcallNode>(*GetCurrentFuncCodeMpAllocator(), OP_icall);
319 DEBUG_ASSERT(stmt != nullptr, "stmt is null");
320 stmt->SetOpnds(args);
321 return stmt;
322 }
323
CreateStmtIcallproto(const MapleVector<BaseNode * > & args,const TyIdx & prototypeIdx)324 IcallNode *MIRBuilder::CreateStmtIcallproto(const MapleVector<BaseNode *> &args, const TyIdx &prototypeIdx)
325 {
326 auto *stmt = NewNode<IcallNode>(*GetCurrentFuncCodeMpAllocator(), OP_icallproto);
327 DEBUG_ASSERT(stmt != nullptr, "stmt is null");
328 stmt->SetOpnds(args);
329 stmt->SetRetTyIdx(prototypeIdx);
330 return stmt;
331 }
332
CreateStmtIcallAssigned(const MapleVector<BaseNode * > & args,const MIRSymbol & ret)333 IcallNode *MIRBuilder::CreateStmtIcallAssigned(const MapleVector<BaseNode *> &args, const MIRSymbol &ret)
334 {
335 auto *stmt = NewNode<IcallNode>(*GetCurrentFuncCodeMpAllocator(), OP_icallassigned);
336 CallReturnVector nrets(GetCurrentFuncCodeMpAllocator()->Adapter());
337 CHECK_FATAL((ret.GetStorageClass() == kScAuto || ret.GetStorageClass() == kScFormal ||
338 ret.GetStorageClass() == kScExtern || ret.GetStorageClass() == kScGlobal),
339 "unknown classtype! check it!");
340 nrets.emplace_back(CallReturnPair(ret.GetStIdx(), RegFieldPair(0, 0)));
341 stmt->SetNumOpnds(args.size());
342 stmt->GetNopnd().resize(stmt->GetNumOpnds());
343 stmt->SetReturnVec(nrets);
344 for (size_t i = 0; i < stmt->GetNopndSize(); ++i) {
345 stmt->SetNOpndAt(i, args.at(i));
346 }
347 stmt->SetRetTyIdx(ret.GetTyIdx());
348 return stmt;
349 }
350
CreateStmtIcallAssigned(const MapleVector<BaseNode * > & args,PregIdx pregIdx)351 IcallNode *MIRBuilder::CreateStmtIcallAssigned(const MapleVector<BaseNode *> &args, PregIdx pregIdx)
352 {
353 auto *stmt = NewNode<IcallNode>(*GetCurrentFuncCodeMpAllocator(), OP_icallassigned);
354 CallReturnVector nrets(GetCurrentFuncCodeMpAllocator()->Adapter());
355 nrets.emplace_back(StIdx(), RegFieldPair(0, pregIdx));
356 stmt->SetNumOpnds(args.size());
357 stmt->GetNopnd().resize(stmt->GetNumOpnds());
358 stmt->SetReturnVec(nrets);
359 for (size_t i = 0; i < stmt->GetNopndSize(); ++i) {
360 stmt->SetNOpndAt(i, args.at(i));
361 }
362 auto *preg = GetCurrentFunction()->GetPregTab()->PregFromPregIdx(pregIdx);
363 DEBUG_ASSERT(preg, "preg should be created before used");
364 if (preg->GetMIRType() == nullptr) {
365 stmt->SetRetTyIdx(TyIdx(preg->GetPrimType()));
366 } else {
367 stmt->SetRetTyIdx(preg->GetMIRType()->GetTypeIndex());
368 }
369 return stmt;
370 }
371
CreateStmtIntrinsicCall(MIRIntrinsicID idx,const MapleVector<BaseNode * > & arguments,TyIdx tyIdx)372 IntrinsiccallNode *MIRBuilder::CreateStmtIntrinsicCall(MIRIntrinsicID idx, const MapleVector<BaseNode *> &arguments,
373 TyIdx tyIdx)
374 {
375 auto *stmt = NewNode<IntrinsiccallNode>(
376 *GetCurrentFuncCodeMpAllocator(), tyIdx == 0u ? OP_intrinsiccall : OP_intrinsiccallwithtype, idx);
377 stmt->SetTyIdx(tyIdx);
378 stmt->SetOpnds(arguments);
379 return stmt;
380 }
381
CreateStmtCallRegassigned(PUIdx puIdx,const MapleVector<BaseNode * > & args,PregIdx pRegIdx,Opcode opcode)382 CallNode *MIRBuilder::CreateStmtCallRegassigned(PUIdx puIdx, const MapleVector<BaseNode *> &args, PregIdx pRegIdx,
383 Opcode opcode)
384 {
385 auto *stmt = NewNode<CallNode>(*GetCurrentFuncCodeMpAllocator(), opcode, puIdx);
386 DEBUG_ASSERT(stmt != nullptr, "stmt is null");
387 stmt->SetOpnds(args);
388 if (pRegIdx > 0) {
389 stmt->GetReturnVec().push_back(CallReturnPair(StIdx(), RegFieldPair(0, pRegIdx)));
390 }
391 return stmt;
392 }
393
CreateStmtIntrinsicCallAssigned(MIRIntrinsicID idx,const MapleVector<BaseNode * > & args,PregIdx retPregIdx1,PregIdx retPregIdx2)394 IntrinsiccallNode *MIRBuilder::CreateStmtIntrinsicCallAssigned(MIRIntrinsicID idx, const MapleVector<BaseNode *> &args,
395 PregIdx retPregIdx1, PregIdx retPregIdx2)
396 {
397 auto *stmt =
398 NewNode<IntrinsiccallNode>(*GetCurrentFuncCodeMpAllocator(), OP_intrinsiccallassigned, idx);
399 DEBUG_ASSERT(stmt != nullptr, "stmt is null");
400 stmt->SetOpnds(args);
401 if (retPregIdx1 > 0) {
402 stmt->GetReturnVec().push_back(CallReturnPair(StIdx(), RegFieldPair(0, retPregIdx1)));
403 }
404 if (retPregIdx2 > 0) {
405 stmt->GetReturnVec().push_back(CallReturnPair(StIdx(), RegFieldPair(0, retPregIdx2)));
406 }
407 return stmt;
408 }
409
CreateStmtReturn(BaseNode * rVal)410 NaryStmtNode *MIRBuilder::CreateStmtReturn(BaseNode *rVal)
411 {
412 auto *stmt = NewNode<NaryStmtNode>(*GetCurrentFuncCodeMpAllocator(), OP_return);
413 DEBUG_ASSERT(stmt != nullptr, "stmt is null");
414 stmt->PushOpnd(rVal);
415 return stmt;
416 }
417
CreateStmtUnary(Opcode op,BaseNode * rVal)418 UnaryStmtNode *MIRBuilder::CreateStmtUnary(Opcode op, BaseNode *rVal)
419 {
420 return NewNode<UnaryStmtNode>(op, kPtyInvalid, rVal);
421 }
422
CreateStmtIf(BaseNode * cond)423 IfStmtNode *MIRBuilder::CreateStmtIf(BaseNode *cond)
424 {
425 auto *ifStmt = NewNode<IfStmtNode>();
426 ifStmt->SetOpnd(cond, 0);
427 BlockNode *thenBlock = NewNode<BlockNode>();
428 ifStmt->SetThenPart(thenBlock);
429 return ifStmt;
430 }
431
CreateStmtSwitch(BaseNode * opnd,LabelIdx defaultLabel,const CaseVector & switchTable)432 SwitchNode *MIRBuilder::CreateStmtSwitch(BaseNode *opnd, LabelIdx defaultLabel, const CaseVector &switchTable)
433 {
434 auto *switchNode = NewNode<SwitchNode>(*GetCurrentFuncCodeMpAllocator(), defaultLabel, opnd);
435 switchNode->SetSwitchTable(switchTable);
436 return switchNode;
437 }
438
CreateStmtGoto(Opcode o,LabelIdx labIdx)439 GotoNode *MIRBuilder::CreateStmtGoto(Opcode o, LabelIdx labIdx)
440 {
441 return NewNode<GotoNode>(o, labIdx);
442 }
443
CreateStmtLabel(LabelIdx labIdx)444 LabelNode *MIRBuilder::CreateStmtLabel(LabelIdx labIdx)
445 {
446 return NewNode<LabelNode>(labIdx);
447 }
448
CreateStmtComment(const std::string & cmnt)449 StmtNode *MIRBuilder::CreateStmtComment(const std::string &cmnt)
450 {
451 return NewNode<CommentNode>(*GetCurrentFuncCodeMpAllocator(), cmnt);
452 }
453
CreateStmtCondGoto(BaseNode * cond,Opcode op,LabelIdx labIdx)454 CondGotoNode *MIRBuilder::CreateStmtCondGoto(BaseNode *cond, Opcode op, LabelIdx labIdx)
455 {
456 return NewNode<CondGotoNode>(op, labIdx, cond);
457 }
458
GetCurrentFuncCodeMp()459 MemPool *MIRBuilder::GetCurrentFuncCodeMp()
460 {
461 if (MIRFunction *curFunction = GetCurrentFunction()) {
462 return curFunction->GetCodeMemPool();
463 }
464 return mirModule->GetMemPool();
465 }
466
GetCurrentFuncCodeMpAllocator()467 MapleAllocator *MIRBuilder::GetCurrentFuncCodeMpAllocator()
468 {
469 if (MIRFunction *curFunction = GetCurrentFunction()) {
470 return &curFunction->GetCodeMPAllocator();
471 }
472 return &mirModule->GetMPAllocator();
473 }
474
MIRBuilderExt(MIRModule * module)475 MIRBuilderExt::MIRBuilderExt(MIRModule *module) : MIRBuilder(module) {}
476 } // namespace maple
477