• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef MAPLE_IR_INCLUDE_MIR_FUNCTION_H
17 #define MAPLE_IR_INCLUDE_MIR_FUNCTION_H
18 #include <string>
19 #include "mir_module.h"
20 #include "mir_const.h"
21 #include "mir_symbol.h"
22 #include "mir_preg.h"
23 #include "intrinsics.h"
24 #include "file_layout.h"
25 #include "mir_nodes.h"
26 #include "mir_type.h"
27 #include "mir_scope.h"
28 #include "profile.h"
29 #include "func_desc.h"
30 
31 #define DEBUGME true
32 
33 namespace maple {
34 enum PointerAttr : uint32_t { kPointerUndeiced = 0x1, kPointerNull = 0x2, kPointerNoNull = 0x3 };
35 
36 enum FuncAttrProp : uint32_t {
37     kNoThrowException = 0x1,
38     kNoRetNewlyAllocObj = 0x2,
39     kNoDefEffect = 0x4,
40     kNoDefArgEffect = 0x8,
41     kPureFunc = 0x10,
42     kIpaSeen = 0x20,
43     kUseEffect = 0x40,
44     kDefEffect = 0x80
45 };
46 
47 // describe a formal definition in a function declaration
48 class FormalDef {
49 public:
50     GStrIdx formalStrIdx = GStrIdx(0);  // used when processing the prototype
51     MIRSymbol *formalSym = nullptr;     // used in the function definition
52     TyIdx formalTyIdx = TyIdx();
53     TypeAttrs formalAttrs = TypeAttrs();  // the formal's type attributes
54 
FormalDef()55     FormalDef() {};
~FormalDef()56     virtual ~FormalDef() {}
FormalDef(MIRSymbol * s,const TyIdx & tidx,const TypeAttrs & at)57     FormalDef(MIRSymbol *s, const TyIdx &tidx, const TypeAttrs &at) : formalSym(s), formalTyIdx(tidx), formalAttrs(at)
58     {
59     }
FormalDef(const GStrIdx & sidx,MIRSymbol * s,const TyIdx & tidx,const TypeAttrs & at)60     FormalDef(const GStrIdx &sidx, MIRSymbol *s, const TyIdx &tidx, const TypeAttrs &at)
61         : formalStrIdx(sidx), formalSym(s), formalTyIdx(tidx), formalAttrs(at)
62     {
63     }
64 };
65 
66 class MeFunction;         // circular dependency exists, no other choice
67 class EAConnectionGraph;  // circular dependency exists, no other choice
68 class MIRFunction {
69 public:
MIRFunction(MIRModule * mod,StIdx idx)70     MIRFunction(MIRModule *mod, StIdx idx) : module(mod), symbolTableIdx(idx)
71     {
72         scope = module->GetMemPool()->New<MIRScope>(mod);
73     }
74 
75     ~MIRFunction() = default;
76 
77     void Dump(bool withoutBody = false);
78     void DumpUpFormal(int32 indent) const;
79     void DumpFrame(int32 indent) const;
80     void DumpFuncBody(int32 indent);
81     void DumpScope();
82     const MIRSymbol *GetFuncSymbol() const;
83     MIRSymbol *GetFuncSymbol();
84 
85     void SetBaseClassFuncNames(GStrIdx strIdx);
SetMemPool(MemPool * memPool)86     void SetMemPool(MemPool *memPool)
87     {
88         SetCodeMemPool(memPool);
89         codeMemPoolAllocator.SetMemPool(codeMemPool);
90     }
91 
92     /// update signature_strIdx, basefunc_strIdx, baseclass_strIdx, basefunc_withtype_strIdx
93     /// without considering baseclass_strIdx, basefunc_strIdx's original non-zero values
94     /// \param strIdx full_name strIdx of the new function name
95     void OverrideBaseClassFuncNames(GStrIdx strIdx);
96     const std::string &GetName() const;
97 
98     GStrIdx GetNameStrIdx() const;
99 
100     const std::string &GetBaseClassName() const;
101 
102     const std::string &GetBaseFuncName() const;
103 
104     const std::string &GetBaseFuncNameWithType() const;
105 
106     const std::string &GetBaseFuncSig() const;
107 
108     const std::string &GetSignature() const;
109 
GetBaseClassNameStrIdx()110     GStrIdx GetBaseClassNameStrIdx() const
111     {
112         return baseClassStrIdx;
113     }
114 
GetBaseFuncNameStrIdx()115     GStrIdx GetBaseFuncNameStrIdx() const
116     {
117         return baseFuncStrIdx;
118     }
119 
GetBaseFuncNameWithTypeStrIdx()120     GStrIdx GetBaseFuncNameWithTypeStrIdx() const
121     {
122         return baseFuncWithTypeStrIdx;
123     }
124 
GetBaseFuncSigStrIdx()125     GStrIdx GetBaseFuncSigStrIdx() const
126     {
127         return baseFuncSigStrIdx;
128     }
129 
SetBaseClassNameStrIdx(GStrIdx id)130     void SetBaseClassNameStrIdx(GStrIdx id)
131     {
132         baseClassStrIdx = id;
133     }
134 
SetBaseFuncNameStrIdx(GStrIdx id)135     void SetBaseFuncNameStrIdx(GStrIdx id)
136     {
137         baseFuncStrIdx = id;
138     }
139 
SetBaseFuncNameWithTypeStrIdx(GStrIdx id)140     void SetBaseFuncNameWithTypeStrIdx(GStrIdx id)
141     {
142         baseFuncWithTypeStrIdx = id;
143     }
144 
145     const MIRType *GetReturnType() const;
146     MIRType *GetReturnType();
IsReturnVoid()147     bool IsReturnVoid() const
148     {
149         return GetReturnType()->GetPrimType() == PTY_void;
150     }
GetReturnTyIdx()151     TyIdx GetReturnTyIdx() const
152     {
153         CHECK_FATAL(funcType != nullptr, "funcType is nullptr");
154         return funcType->GetRetTyIdx();
155     }
SetReturnTyIdx(TyIdx tyidx)156     void SetReturnTyIdx(TyIdx tyidx)
157     {
158         CHECK_FATAL(funcType != nullptr, "funcType is nullptr");
159         funcType->SetRetTyIdx(tyidx);
160     }
161 
162     const MIRType *GetClassType() const;
GetClassTyIdx()163     TyIdx GetClassTyIdx() const
164     {
165         return classTyIdx;
166     }
SetClassTyIdx(TyIdx tyIdx)167     void SetClassTyIdx(TyIdx tyIdx)
168     {
169         classTyIdx = tyIdx;
170     }
SetClassTyIdx(uint32 idx)171     void SetClassTyIdx(uint32 idx)
172     {
173         classTyIdx.reset(idx);
174     }
175 
AddArgument(MIRSymbol * st)176     void AddArgument(MIRSymbol *st)
177     {
178         DEBUG_ASSERT(st != nullptr, "null ptr check");
179         FormalDef formalDef(st->GetNameStrIdx(), st, st->GetTyIdx(), st->GetAttrs());
180         formalDefVec.push_back(formalDef);
181     }
182 
AddFormalDef(const FormalDef & formalDef)183     void AddFormalDef(const FormalDef &formalDef)
184     {
185         formalDefVec.push_back(formalDef);
186     }
187 
GetParamSize()188     size_t GetParamSize() const
189     {
190         CHECK_FATAL(funcType != nullptr, "funcType is nullptr");
191         return funcType->GetParamTypeList().size();
192     }
193 
GetParamTypes()194     auto &GetParamTypes() const
195     {
196         CHECK_FATAL(funcType != nullptr, "funcType is nullptr");
197         return funcType->GetParamTypeList();
198     }
199 
GetNthParamTyIdx(size_t i)200     TyIdx GetNthParamTyIdx(size_t i) const
201     {
202         DEBUG_ASSERT(i < funcType->GetParamTypeList().size(), "array index out of range");
203         return funcType->GetParamTypeList()[i];
204     }
205 
206     const MIRType *GetNthParamType(size_t i) const;
207     MIRType *GetNthParamType(size_t i);
208 
GetNthParamAttr(size_t i)209     const TypeAttrs &GetNthParamAttr(size_t i) const
210     {
211         DEBUG_ASSERT(i < formalDefVec.size(), "array index out of range");
212         DEBUG_ASSERT(formalDefVec[i].formalSym != nullptr, "null ptr check");
213         return formalDefVec[i].formalSym->GetAttrs();
214     }
215 
216     void UpdateFuncTypeAndFormals(const std::vector<MIRSymbol *> &symbols, bool clearOldArgs = false);
217     void UpdateFuncTypeAndFormalsAndReturnType(const std::vector<MIRSymbol *> &symbols, const TyIdx &retTyIdx,
218                                                bool clearOldArgs = false);
219     LabelIdx GetOrCreateLableIdxFromName(const std::string &name);
GetLabelStringIndex(LabelIdx labelIdx)220     GStrIdx GetLabelStringIndex(LabelIdx labelIdx) const
221     {
222         CHECK_FATAL(labelTab != nullptr, "labelTab is nullptr");
223         DEBUG_ASSERT(labelIdx < labelTab->Size(), "index out of range in GetLabelStringIndex");
224         return labelTab->GetSymbolFromStIdx(labelIdx);
225     }
GetLabelName(LabelIdx labelIdx)226     const std::string &GetLabelName(LabelIdx labelIdx) const
227     {
228         GStrIdx strIdx = GetLabelStringIndex(labelIdx);
229         return GlobalTables::GetStrTable().GetStringFromStrIdx(strIdx);
230     }
231 
232     const MIRSymbol *GetLocalOrGlobalSymbol(const StIdx &idx, bool checkFirst = false) const;
233     MIRSymbol *GetLocalOrGlobalSymbol(const StIdx &idx, bool checkFirst = false);
234 
235     void SetAttrsFromSe(uint8 specialEffect);
236 
GetAttrs()237     const FuncAttrs &GetAttrs() const
238     {
239         return funcAttrs;
240     }
241 
SetAttrs(FuncAttrs attr)242     void SetAttrs(FuncAttrs attr)
243     {
244         funcAttrs = attr;
245     }
246 
GetAttr(FuncAttrKind attrKind)247     bool GetAttr(FuncAttrKind attrKind) const
248     {
249         return funcAttrs.GetAttr(attrKind);
250     }
251 
SetAttr(FuncAttrKind attrKind)252     void SetAttr(FuncAttrKind attrKind)
253     {
254         funcAttrs.SetAttr(attrKind);
255     }
256 
UnSetAttr(FuncAttrKind attrKind)257     void UnSetAttr(FuncAttrKind attrKind)
258     {
259         funcAttrs.SetAttr(attrKind, true);
260     }
261 
IsVarargs()262     bool IsVarargs() const
263     {
264         return funcAttrs.GetAttr(FUNCATTR_varargs);
265     }
266 
IsWeak()267     bool IsWeak() const
268     {
269         return funcAttrs.GetAttr(FUNCATTR_weak);
270     }
271 
IsStatic()272     bool IsStatic() const
273     {
274         return funcAttrs.GetAttr(FUNCATTR_static);
275     }
276 
IsInline()277     bool IsInline() const
278     {
279         return funcAttrs.GetAttr(FUNCATTR_inline);
280     }
281 
IsExtern()282     bool IsExtern() const
283     {
284         return funcAttrs.GetAttr(FUNCATTR_extern);
285     }
286 
IsNative()287     bool IsNative() const
288     {
289         return funcAttrs.GetAttr(FUNCATTR_native);
290     }
291 
IsFinal()292     bool IsFinal() const
293     {
294         return funcAttrs.GetAttr(FUNCATTR_final);
295     }
296 
IsAbstract()297     bool IsAbstract() const
298     {
299         return funcAttrs.GetAttr(FUNCATTR_abstract);
300     }
301 
IsPublic()302     bool IsPublic() const
303     {
304         return funcAttrs.GetAttr(FUNCATTR_public);
305     }
306 
IsPrivate()307     bool IsPrivate() const
308     {
309         return funcAttrs.GetAttr(FUNCATTR_private);
310     }
311 
IsProtected()312     bool IsProtected() const
313     {
314         return funcAttrs.GetAttr(FUNCATTR_protected);
315     }
316 
IsConstructor()317     bool IsConstructor() const
318     {
319         return funcAttrs.GetAttr(FUNCATTR_constructor);
320     }
321 
IsLocal()322     bool IsLocal() const
323     {
324         return funcAttrs.GetAttr(FUNCATTR_local);
325     }
326 
IsNoDefArgEffect()327     bool IsNoDefArgEffect() const
328     {
329         return funcAttrs.GetAttr(FUNCATTR_nodefargeffect);
330     }
331 
IsNoDefEffect()332     bool IsNoDefEffect() const
333     {
334         return funcAttrs.GetAttr(FUNCATTR_nodefeffect);
335     }
336 
IsNoRetGlobal()337     bool IsNoRetGlobal() const
338     {
339         return funcAttrs.GetAttr(FUNCATTR_noretglobal);
340     }
341 
IsNoThrowException()342     bool IsNoThrowException() const
343     {
344         return funcAttrs.GetAttr(FUNCATTR_nothrow_exception);
345     }
346 
IsNoRetArg()347     bool IsNoRetArg() const
348     {
349         return funcAttrs.GetAttr(FUNCATTR_noretarg);
350     }
351 
IsNoPrivateDefEffect()352     bool IsNoPrivateDefEffect() const
353     {
354         return funcAttrs.GetAttr(FUNCATTR_noprivate_defeffect);
355     }
356 
IsIpaSeen()357     bool IsIpaSeen() const
358     {
359         return funcAttrs.GetAttr(FUNCATTR_ipaseen);
360     }
361 
IsPure()362     bool IsPure() const
363     {
364         return funcAttrs.GetAttr(FUNCATTR_pure);
365     }
366 
IsFirstArgReturn()367     bool IsFirstArgReturn() const
368     {
369         return funcAttrs.GetAttr(FUNCATTR_firstarg_return);
370     }
371 
IsUnSafe()372     bool IsUnSafe() const
373     {
374         return !funcAttrs.GetAttr(FUNCATTR_safed) || funcAttrs.GetAttr(FUNCATTR_unsafed);
375     }
376 
IsSafe()377     bool IsSafe() const
378     {
379         return funcAttrs.GetAttr(FUNCATTR_safed);
380     }
381 
SetVarArgs()382     void SetVarArgs()
383     {
384         funcAttrs.SetAttr(FUNCATTR_varargs);
385     }
386 
SetNoDefArgEffect()387     void SetNoDefArgEffect()
388     {
389         funcAttrs.SetAttr(FUNCATTR_nodefargeffect);
390     }
391 
SetNoDefEffect()392     void SetNoDefEffect()
393     {
394         funcAttrs.SetAttr(FUNCATTR_nodefeffect);
395     }
396 
SetNoRetGlobal()397     void SetNoRetGlobal()
398     {
399         funcAttrs.SetAttr(FUNCATTR_noretglobal);
400     }
401 
SetNoThrowException()402     void SetNoThrowException()
403     {
404         funcAttrs.SetAttr(FUNCATTR_nothrow_exception);
405     }
406 
SetNoRetArg()407     void SetNoRetArg()
408     {
409         funcAttrs.SetAttr(FUNCATTR_noretarg);
410     }
411 
SetNoPrivateDefEffect()412     void SetNoPrivateDefEffect()
413     {
414         funcAttrs.SetAttr(FUNCATTR_noprivate_defeffect);
415     }
416 
SetIpaSeen()417     void SetIpaSeen()
418     {
419         funcAttrs.SetAttr(FUNCATTR_ipaseen);
420     }
421 
SetPure()422     void SetPure()
423     {
424         funcAttrs.SetAttr(FUNCATTR_pure);
425     }
426 
SetFirstArgReturn()427     void SetFirstArgReturn()
428     {
429         funcAttrs.SetAttr(FUNCATTR_firstarg_return);
430     }
431 
UnsetNoDefArgEffect()432     void UnsetNoDefArgEffect()
433     {
434         funcAttrs.SetAttr(FUNCATTR_nodefargeffect, true);
435     }
436 
UnsetNoDefEffect()437     void UnsetNoDefEffect()
438     {
439         funcAttrs.SetAttr(FUNCATTR_nodefeffect, true);
440     }
441 
UnsetNoRetGlobal()442     void UnsetNoRetGlobal()
443     {
444         funcAttrs.SetAttr(FUNCATTR_noretglobal, true);
445     }
446 
UnsetNoThrowException()447     void UnsetNoThrowException()
448     {
449         funcAttrs.SetAttr(FUNCATTR_nothrow_exception, true);
450     }
451 
UnsetPure()452     void UnsetPure()
453     {
454         funcAttrs.SetAttr(FUNCATTR_pure, true);
455     }
456 
UnsetNoRetArg()457     void UnsetNoRetArg()
458     {
459         funcAttrs.SetAttr(FUNCATTR_noretarg, true);
460     }
461 
UnsetNoPrivateDefEffect()462     void UnsetNoPrivateDefEffect()
463     {
464         funcAttrs.SetAttr(FUNCATTR_noprivate_defeffect, true);
465     }
466 
467     bool HasCall() const;
468     void SetHasCall();
469 
470     bool IsReturnStruct() const;
471     void SetReturnStruct();
472     void SetReturnStruct(const MIRType &retType);
473 
474     bool IsUserFunc() const;
475     void SetUserFunc();
476 
477     bool IsInfoPrinted() const;
478     void SetInfoPrinted();
479     void ResetInfoPrinted();
480 
481     void SetNoReturn();
482     bool NeverReturns() const;
483 
484     void SetHasSetjmp();
485     bool HasSetjmp() const;
486 
487     void SetHasAsm();
488     bool HasAsm() const;
489 
490     void SetStructReturnedInRegs();
491     bool StructReturnedInRegs() const;
492 
493     void SetReturnStruct(const MIRType *retType);
494 
495     bool IsEmpty() const;
496     bool IsClinit() const;
497     uint32 GetInfo(GStrIdx strIdx) const;
498     uint32 GetInfo(const std::string &str) const;
IsAFormal(const MIRSymbol * st)499     bool IsAFormal(const MIRSymbol *st) const
500     {
501         for (const auto &formalDef : formalDefVec) {
502             if (st == formalDef.formalSym) {
503                 return true;
504             }
505         }
506         return false;
507     }
508 
GetFormalIndex(const MIRSymbol * symbol)509     uint32 GetFormalIndex(const MIRSymbol *symbol) const
510     {
511         for (size_t i = 0; i < formalDefVec.size(); ++i) {
512             if (formalDefVec[i].formalSym == symbol) {
513                 return i;
514             }
515         }
516         return 0xffffffff;
517     }
518 
GetFormalDefFromMIRSymbol(const MIRSymbol * symbol)519     FormalDef &GetFormalDefFromMIRSymbol(const MIRSymbol *symbol)
520     {
521         for (auto &formalDef : formalDefVec) {
522             if (formalDef.formalSym == symbol) {
523                 return formalDef;
524             }
525         }
526         CHECK_FATAL(false, "Impossible.");
527     }
528 
IsAFormalName(const GStrIdx idx)529     bool IsAFormalName(const GStrIdx idx) const
530     {
531         for (const auto &formalDef : formalDefVec) {
532             if (idx == formalDef.formalStrIdx) {
533                 return true;
534             }
535         }
536         return false;
537     }
538 
GetFormalFromName(const GStrIdx idx)539     const FormalDef GetFormalFromName(const GStrIdx idx) const
540     {
541         for (size_t i = 0; i < formalDefVec.size(); ++i) {
542             if (formalDefVec[i].formalStrIdx == idx) {
543                 return formalDefVec[i];
544             }
545         }
546         return FormalDef();
547     }
548 
549     // tell whether this function is a Java method
IsJava()550     bool IsJava() const
551     {
552         return classTyIdx != 0u;
553     }
554 
555     const MIRType *GetNodeType(const BaseNode &node) const;
556 
557 #ifdef DEBUGME
558     void SetUpGDBEnv();
559     void ResetGDBEnv();
560 #endif
ReleaseMemory()561     void ReleaseMemory()
562     {
563         if (codeMemPoolTmp != nullptr) {
564             delete codeMemPoolTmp;
565             codeMemPoolTmp = nullptr;
566         }
567     }
568 
ReleaseCodeMemory()569     void ReleaseCodeMemory()
570     {
571         if (codeMemPool != nullptr) {
572             codeMemPoolAllocator.SetMemPool(nullptr);
573             delete codeMemPool;
574             SetMemPool(nullptr);
575         }
576     }
577 
GetCodeMempool()578     MemPool *GetCodeMempool()
579     {
580         if (useTmpMemPool) {
581             if (codeMemPoolTmp == nullptr) {
582                 codeMemPoolTmp = new ThreadLocalMemPool(memPoolCtrler, "func code mempool");
583                 codeMemPoolTmpAllocator.SetMemPool(codeMemPoolTmp);
584             }
585             return codeMemPoolTmp;
586         }
587         if (codeMemPool == nullptr) {
588             codeMemPool = new ThreadLocalMemPool(memPoolCtrler, "func code mempool");
589             codeMemPoolAllocator.SetMemPool(codeMemPool);
590         }
591         return codeMemPool;
592     }
593 
GetCodeMemPoolAllocator()594     MapleAllocator &GetCodeMemPoolAllocator()
595     {
596         GetCodeMempool();
597         if (useTmpMemPool) {
598             return codeMemPoolTmpAllocator;
599         }
600         return codeMemPoolAllocator;
601     }
602 
GetCodeMempoolAllocator()603     MapleAllocator &GetCodeMempoolAllocator()
604     {
605         if (codeMemPool == nullptr) {
606             codeMemPool = new ThreadLocalMemPool(memPoolCtrler, "func code mempool");
607             codeMemPoolAllocator.SetMemPool(codeMemPool);
608         }
609         return codeMemPoolAllocator;
610     }
611 
GetFuncRetStructTyIdx()612     TyIdx GetFuncRetStructTyIdx()
613     {
614         TyIdx tyIdx = GetFormalDefAt(0).formalTyIdx;
615         MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx);
616         CHECK_FATAL(ty->GetKind() == kTypePointer, "Fake param not a pointer");
617         MIRPtrType *pType = static_cast<MIRPtrType *>(ty);
618         tyIdx = pType->GetPointedTyIdx();
619         CHECK_FATAL(GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx)->IsStructType(), "Must be struct return type");
620         return tyIdx;
621     }
622 
623     void EnterFormals();
624     void NewBody();
625 
GetModule()626     MIRModule *GetModule()
627     {
628         return module;
629     }
630 
GetPuidx()631     PUIdx GetPuidx() const
632     {
633         return puIdx;
634     }
SetPuidx(PUIdx idx)635     void SetPuidx(PUIdx idx)
636     {
637         puIdx = idx;
638     }
639 
GetPuidxOrigin()640     PUIdx GetPuidxOrigin() const
641     {
642         return puIdxOrigin;
643     }
SetPuidxOrigin(PUIdx idx)644     void SetPuidxOrigin(PUIdx idx)
645     {
646         puIdxOrigin = idx;
647     }
648 
GetStIdx()649     StIdx GetStIdx() const
650     {
651         return symbolTableIdx;
652     }
SetStIdx(StIdx stIdx)653     void SetStIdx(StIdx stIdx)
654     {
655         symbolTableIdx = stIdx;
656     }
657 
GetSCCId()658     int32 GetSCCId() const
659     {
660         return sccID;
661     }
SetSCCId(int32 id)662     void SetSCCId(int32 id)
663     {
664         sccID = id;
665     }
666 
GetMIRFuncType()667     MIRFuncType *GetMIRFuncType()
668     {
669         return funcType;
670     }
SetMIRFuncType(MIRFuncType * type)671     void SetMIRFuncType(MIRFuncType *type)
672     {
673         funcType = type;
674     }
675 
GetInferredReturnTyIdx()676     TyIdx GetInferredReturnTyIdx() const
677     {
678         return inferredReturnTyIdx;
679     }
680 
SetInferredReturnTyIdx(TyIdx tyIdx)681     void SetInferredReturnTyIdx(TyIdx tyIdx)
682     {
683         inferredReturnTyIdx = tyIdx;
684     }
685 
GetTypeNameTab()686     MIRTypeNameTable *GetTypeNameTab() const
687     {
688         return typeNameTab;
689     }
690 
AllocTypeNameTab()691     void AllocTypeNameTab()
692     {
693         if (typeNameTab == nullptr) {
694             typeNameTab = module->GetMemPool()->New<MIRTypeNameTable>(module->GetMPAllocator());
695         }
696     }
HaveTypeNameTab()697     bool HaveTypeNameTab() const
698     {
699         return typeNameTab != nullptr;
700     }
GetGStrIdxToTyIdxMap()701     const MapleMap<GStrIdx, TyIdx> &GetGStrIdxToTyIdxMap() const
702     {
703         CHECK_FATAL(typeNameTab != nullptr, "typeNameTab is nullptr");
704         return typeNameTab->GetGStrIdxToTyIdxMap();
705     }
GetTyIdxFromGStrIdx(GStrIdx idx)706     TyIdx GetTyIdxFromGStrIdx(GStrIdx idx) const
707     {
708         CHECK_FATAL(typeNameTab != nullptr, "typeNameTab is nullptr");
709         return typeNameTab->GetTyIdxFromGStrIdx(idx);
710     }
SetGStrIdxToTyIdx(GStrIdx gStrIdx,TyIdx tyIdx)711     void SetGStrIdxToTyIdx(GStrIdx gStrIdx, TyIdx tyIdx)
712     {
713         CHECK_FATAL(typeNameTab != nullptr, "typeNameTab is nullptr");
714         typeNameTab->SetGStrIdxToTyIdx(gStrIdx, tyIdx);
715     }
716 
GetLabelTabItem(LabelIdx labelIdx)717     const std::string &GetLabelTabItem(LabelIdx labelIdx) const
718     {
719         CHECK_FATAL(labelTab != nullptr, "labelTab is nullptr");
720         return labelTab->GetName(labelIdx);
721     }
722 
AllocLabelTab()723     void AllocLabelTab()
724     {
725         if (labelTab == nullptr) {
726             labelTab = module->GetMemPool()->New<MIRLabelTable>(module->GetMPAllocator());
727         }
728     }
729 
GetPregTab()730     MIRPregTable *GetPregTab() const
731     {
732         return pregTab;
733     }
734 
SetPregTab(MIRPregTable * tab)735     void SetPregTab(MIRPregTable *tab)
736     {
737         pregTab = tab;
738     }
AllocPregTab()739     void AllocPregTab()
740     {
741         if (pregTab == nullptr) {
742             pregTab = module->GetMemPool()->New<MIRPregTable>(&module->GetMPAllocator());
743         }
744     }
GetPregItem(PregIdx idx)745     MIRPreg *GetPregItem(PregIdx idx)
746     {
747         return const_cast<MIRPreg *>(const_cast<const MIRFunction *>(this)->GetPregItem(idx));
748     }
GetPregItem(PregIdx idx)749     const MIRPreg *GetPregItem(PregIdx idx) const
750     {
751         return pregTab->PregFromPregIdx(idx);
752     }
753 
GetBody()754     BlockNode *GetBody()
755     {
756         return body;
757     }
GetBody()758     const BlockNode *GetBody() const
759     {
760         return body;
761     }
SetBody(BlockNode * node)762     void SetBody(BlockNode *node)
763     {
764         body = node;
765     }
766 
GetLastPosBody()767     BlockNode *GetLastPosBody()
768     {
769         return bodyLast;
770     }
GetLastPosBody()771     const BlockNode *GetLastPosBody() const
772     {
773         return bodyLast;
774     }
SetLastPosBody(BlockNode * node)775     void SetLastPosBody(BlockNode *node)
776     {
777         bodyLast = node;
778     }
779 
GetSrcPosition()780     SrcPosition &GetSrcPosition()
781     {
782         DEBUG_ASSERT(GetFuncSymbol() != nullptr, "null ptr check");
783         return GetFuncSymbol()->GetSrcPosition();
784     }
785 
SetSrcPosition(const SrcPosition & position)786     void SetSrcPosition(const SrcPosition &position)
787     {
788         DEBUG_ASSERT(GetFuncSymbol() != nullptr, "null ptr check");
789         GetFuncSymbol()->SetSrcPosition(position);
790     }
791 
GetFuncAttrs()792     const FuncAttrs &GetFuncAttrs() const
793     {
794         return funcAttrs;
795     }
GetFuncAttrs()796     FuncAttrs &GetFuncAttrs()
797     {
798         return funcAttrs;
799     }
800 
SetFuncAttrs(const FuncAttrs & attrs)801     void SetFuncAttrs(const FuncAttrs &attrs)
802     {
803         funcAttrs = attrs;
804     }
SetFuncAttrs(uint64 attrFlag)805     void SetFuncAttrs(uint64 attrFlag)
806     {
807         funcAttrs.SetAttrFlag(attrFlag);
808     }
809 
GetFlag()810     uint32 GetFlag() const
811     {
812         return flag;
813     }
SetFlag(uint32 newFlag)814     void SetFlag(uint32 newFlag)
815     {
816         flag = newFlag;
817     }
818 
GetHashCode()819     uint16 GetHashCode() const
820     {
821         return hashCode;
822     }
SetHashCode(uint16 newHashCode)823     void SetHashCode(uint16 newHashCode)
824     {
825         hashCode = newHashCode;
826     }
827 
SetFileIndex(uint32 newFileIndex)828     void SetFileIndex(uint32 newFileIndex)
829     {
830         fileIndex = newFileIndex;
831     }
832 
GetInfoVector()833     MIRInfoVector &GetInfoVector()
834     {
835         return info;
836     }
837 
GetInfoPair(size_t i)838     const MIRInfoPair &GetInfoPair(size_t i) const
839     {
840         return info.at(i);
841     }
842 
PushbackMIRInfo(const MIRInfoPair & pair)843     void PushbackMIRInfo(const MIRInfoPair &pair)
844     {
845         info.push_back(pair);
846     }
847 
SetMIRInfoNum(size_t idx,uint32 num)848     void SetMIRInfoNum(size_t idx, uint32 num)
849     {
850         info[idx].second = num;
851     }
852 
InfoIsString()853     MapleVector<bool> &InfoIsString()
854     {
855         return infoIsString;
856     }
857 
PushbackIsString(bool isString)858     void PushbackIsString(bool isString)
859     {
860         infoIsString.push_back(isString);
861     }
862 
GetScope()863     MIRScope *GetScope()
864     {
865         return scope;
866     }
867 
NeedEmitAliasInfo()868     bool NeedEmitAliasInfo() const
869     {
870         return scope->NeedEmitAliasInfo();
871     }
872 
GetAliasVarMap()873     MapleMap<GStrIdx, MIRAliasVars> &GetAliasVarMap()
874     {
875         return scope->GetAliasVarMap();
876     }
877 
SetAliasVarMap(GStrIdx idx,const MIRAliasVars & vars)878     void SetAliasVarMap(GStrIdx idx, const MIRAliasVars &vars)
879     {
880         scope->SetAliasVarMap(idx, vars);
881     }
882 
AddAliasVarMap(GStrIdx idx,const MIRAliasVars & vars)883     void AddAliasVarMap(GStrIdx idx, const MIRAliasVars &vars)
884     {
885         scope->AddAliasVarMap(idx, vars);
886     }
887 
HasVlaOrAlloca()888     bool HasVlaOrAlloca() const
889     {
890         return hasVlaOrAlloca;
891     }
SetVlaOrAlloca(bool has)892     void SetVlaOrAlloca(bool has)
893     {
894         hasVlaOrAlloca = has;
895     }
896 
897     // Default freq is the lastStmtFreq
HasFreqMap()898     bool HasFreqMap() const
899     {
900         return freqLastMap != nullptr;
901     }
902 
HasFirstFreqMap()903     bool HasFirstFreqMap() const
904     {
905         return freqFirstMap != nullptr;
906     }
907 
GetFirstFreqMap()908     const MapleMap<uint32, uint32> &GetFirstFreqMap() const
909     {
910         return *freqFirstMap;
911     }
912 
SetFirstFreqMap(uint32 stmtID,uint32 freq)913     void SetFirstFreqMap(uint32 stmtID, uint32 freq)
914     {
915         if (freqFirstMap == nullptr) {
916             freqFirstMap = module->GetMemPool()->New<MapleMap<uint32, uint32>>(module->GetMPAllocator().Adapter());
917         }
918         (*freqFirstMap)[stmtID] = freq;
919     }
920 
GetLastFreqMap()921     const MapleMap<uint32, uint32> &GetLastFreqMap() const
922     {
923         return *freqLastMap;
924     }
925 
GetFreqFromLastStmt(uint32 stmtId)926     int32 GetFreqFromLastStmt(uint32 stmtId)
927     {
928         if (freqLastMap == nullptr) {
929             return -1;
930         }
931         if ((*freqLastMap).find(stmtId) == (*freqLastMap).end()) {
932             return -1;
933         }
934         return static_cast<int32>((*freqLastMap)[stmtId]);
935     }
936 
GetFreqFromFirstStmt(uint32 stmtId)937     int32 GetFreqFromFirstStmt(uint32 stmtId)
938     {
939         if (freqFirstMap == nullptr) {
940             return -1;
941         }
942         if ((*freqFirstMap).find(stmtId) == (*freqFirstMap).end()) {
943             return -1;
944         }
945         return static_cast<int32>((*freqFirstMap)[stmtId]);
946     }
947 
SetLastFreqMap(uint32 stmtID,uint32 freq)948     void SetLastFreqMap(uint32 stmtID, uint32 freq)
949     {
950         if (freqLastMap == nullptr) {
951             freqLastMap = module->GetMemPool()->New<MapleMap<uint32, uint32>>(module->GetMPAllocator().Adapter());
952         }
953         (*freqLastMap)[stmtID] = freq;
954     }
955 
WithLocInfo()956     bool WithLocInfo() const
957     {
958         return withLocInfo;
959     }
SetWithLocInfo(bool withInfo)960     void SetWithLocInfo(bool withInfo)
961     {
962         withLocInfo = withInfo;
963     }
964 
IsDirty()965     bool IsDirty() const
966     {
967         return isDirty;
968     }
SetDirty(bool dirty)969     void SetDirty(bool dirty)
970     {
971         isDirty = dirty;
972     }
973 
IsFromMpltInline()974     bool IsFromMpltInline() const
975     {
976         return fromMpltInline;
977     }
SetFromMpltInline(bool isInline)978     void SetFromMpltInline(bool isInline)
979     {
980         fromMpltInline = isInline;
981     }
982 
GetLayoutType()983     uint8 GetLayoutType() const
984     {
985         return layoutType;
986     }
SetLayoutType(uint8 type)987     void SetLayoutType(uint8 type)
988     {
989         layoutType = type;
990     }
991 
GetCallTimes()992     uint32 GetCallTimes() const
993     {
994         return callTimes;
995     }
SetCallTimes(uint32 times)996     void SetCallTimes(uint32 times)
997     {
998         callTimes = times;
999     }
1000 
GetFrameSize()1001     uint32 GetFrameSize() const
1002     {
1003         return frameSize;
1004     }
SetFrameSize(uint32 size)1005     void SetFrameSize(uint32 size)
1006     {
1007         frameSize = size;
1008     }
1009 
GetUpFormalSize()1010     uint32 GetUpFormalSize() const
1011     {
1012         return upFormalSize;
1013     }
SetUpFormalSize(uint32 size)1014     void SetUpFormalSize(uint32 size)
1015     {
1016         upFormalSize = size;
1017     }
1018 
GetOutParmSize()1019     uint32 GetOutParmSize() const
1020     {
1021         return outParmSize;
1022     }
SetOutParmSize(uint32 size)1023     void SetOutParmSize(uint32 size)
1024     {
1025         outParmSize = size;
1026     }
1027 
GetModuleId()1028     uint16 GetModuleId() const
1029     {
1030         return moduleID;
1031     }
SetModuleID(uint16 id)1032     void SetModuleID(uint16 id)
1033     {
1034         moduleID = id;
1035     }
1036 
GetFuncSize()1037     uint32 GetFuncSize() const
1038     {
1039         return funcSize;
1040     }
SetFuncSize(uint32 size)1041     void SetFuncSize(uint32 size)
1042     {
1043         funcSize = size;
1044     }
1045 
GetTempCount()1046     uint32 GetTempCount() const
1047     {
1048         return tempCount;
1049     }
IncTempCount()1050     void IncTempCount()
1051     {
1052         ++tempCount;
1053     }
1054 
GetFormalWordsTypeTagged()1055     uint8 *GetFormalWordsTypeTagged() const
1056     {
1057         return formalWordsTypeTagged;
1058     }
SetFormalWordsTypeTagged(uint8 * tagged)1059     void SetFormalWordsTypeTagged(uint8 *tagged)
1060     {
1061         formalWordsTypeTagged = tagged;
1062     }
GetFwtAddress()1063     uint8 **GetFwtAddress()
1064     {
1065         return &formalWordsTypeTagged;
1066     }
1067 
GetLocalWordsTypeTagged()1068     uint8 *GetLocalWordsTypeTagged() const
1069     {
1070         return localWordsTypeTagged;
1071     }
SetLocalWordsTypeTagged(uint8 * tagged)1072     void SetLocalWordsTypeTagged(uint8 *tagged)
1073     {
1074         localWordsTypeTagged = tagged;
1075     }
GetLwtAddress()1076     uint8 **GetLwtAddress()
1077     {
1078         return &localWordsTypeTagged;
1079     }
1080 
GetFormalWordsRefCounted()1081     uint8 *GetFormalWordsRefCounted() const
1082     {
1083         return formalWordsRefCounted;
1084     }
SetFormalWordsRefCounted(uint8 * counted)1085     void SetFormalWordsRefCounted(uint8 *counted)
1086     {
1087         formalWordsRefCounted = counted;
1088     }
GetFwrAddress()1089     uint8 **GetFwrAddress()
1090     {
1091         return &formalWordsRefCounted;
1092     }
1093 
GetLocalWordsRefCounted()1094     uint8 *GetLocalWordsRefCounted() const
1095     {
1096         return localWordsRefCounted;
1097     }
SetLocalWordsRefCounted(uint8 * counted)1098     void SetLocalWordsRefCounted(uint8 *counted)
1099     {
1100         localWordsRefCounted = counted;
1101     }
1102 
GetMeFunc()1103     MeFunction *GetMeFunc()
1104     {
1105         return meFunc;
1106     }
1107 
SetMeFunc(MeFunction * func)1108     void SetMeFunc(MeFunction *func)
1109     {
1110         meFunc = func;
1111     }
1112 
GetEACG()1113     EAConnectionGraph *GetEACG()
1114     {
1115         return eacg;
1116     }
SetEACG(EAConnectionGraph * eacgVal)1117     void SetEACG(EAConnectionGraph *eacgVal)
1118     {
1119         eacg = eacgVal;
1120     }
1121 
SetFormalDefVec(const MapleVector<FormalDef> & currFormals)1122     void SetFormalDefVec(const MapleVector<FormalDef> &currFormals)
1123     {
1124         formalDefVec = currFormals;
1125     }
1126 
GetFormalDefVec()1127     MapleVector<FormalDef> &GetFormalDefVec()
1128     {
1129         return formalDefVec;
1130     }
1131 
GetFormalDefAt(size_t i)1132     const FormalDef &GetFormalDefAt(size_t i) const
1133     {
1134         return formalDefVec[i];
1135     }
1136 
GetFormalDefAt(size_t i)1137     FormalDef &GetFormalDefAt(size_t i)
1138     {
1139         return formalDefVec[i];
1140     }
1141 
GetFormal(size_t i)1142     const MIRSymbol *GetFormal(size_t i) const
1143     {
1144         return formalDefVec[i].formalSym;
1145     }
1146 
GetFormal(size_t i)1147     MIRSymbol *GetFormal(size_t i)
1148     {
1149         return formalDefVec[i].formalSym;
1150     }
1151 
GetFormalName(size_t i)1152     const std::string &GetFormalName(size_t i) const
1153     {
1154         auto *formal = formalDefVec[i].formalSym;
1155         if (formal != nullptr) {
1156             return formal->GetName();
1157         }
1158         return GlobalTables::GetStrTable().GetStringFromStrIdx(formalDefVec[i].formalStrIdx);
1159     }
1160 
GetFormalCount()1161     size_t GetFormalCount() const
1162     {
1163         return formalDefVec.size();
1164     }
1165 
ClearFormals()1166     void ClearFormals()
1167     {
1168         formalDefVec.clear();
1169     }
1170 
ClearArguments()1171     void ClearArguments()
1172     {
1173         formalDefVec.clear();
1174         funcType->GetParamTypeList().clear();
1175         funcType->GetParamAttrsList().clear();
1176     }
1177 
GetSymbolTabSize()1178     size_t GetSymbolTabSize() const
1179     {
1180         DEBUG_ASSERT(symTab != nullptr, "symTab is nullptr");
1181         return symTab->GetSymbolTableSize();
1182     }
1183     MIRSymbol *GetSymbolTabItem(uint32 idx, bool checkFirst = false) const
1184     {
1185         return symTab->GetSymbolFromStIdx(idx, checkFirst);
1186     }
GetSymTab()1187     const MIRSymbolTable *GetSymTab() const
1188     {
1189         return symTab;
1190     }
GetSymTab()1191     MIRSymbolTable *GetSymTab()
1192     {
1193         return symTab;
1194     }
AllocSymTab()1195     void AllocSymTab()
1196     {
1197         if (symTab == nullptr) {
1198             symTab = module->GetMemPool()->New<MIRSymbolTable>(module->GetMPAllocator());
1199         }
1200     }
GetLabelTab()1201     MIRLabelTable *GetLabelTab() const
1202     {
1203         CHECK_FATAL(labelTab != nullptr, "must be");
1204         return labelTab;
1205     }
GetLabelTab()1206     MIRLabelTable *GetLabelTab()
1207     {
1208         if (labelTab == nullptr) {
1209             labelTab = module->GetMemPool()->New<MIRLabelTable>(module->GetMPAllocator());
1210         }
1211         return labelTab;
1212     }
SetLabelTab(MIRLabelTable * currLabelTab)1213     void SetLabelTab(MIRLabelTable *currLabelTab)
1214     {
1215         labelTab = currLabelTab;
1216     }
1217 
GetRetRefSym()1218     const MapleSet<MIRSymbol *> &GetRetRefSym() const
1219     {
1220         return retRefSym;
1221     }
InsertMIRSymbol(MIRSymbol * sym)1222     void InsertMIRSymbol(MIRSymbol *sym)
1223     {
1224         (void)retRefSym.insert(sym);
1225     }
1226 
GetDataMemPool()1227     MemPool *GetDataMemPool() const
1228     {
1229         return module->GetMemPool();
1230     }
1231 
GetCodeMemPool()1232     MemPool *GetCodeMemPool()
1233     {
1234         if (codeMemPool == nullptr) {
1235             codeMemPool = new ThreadLocalMemPool(memPoolCtrler, "func code mempool");
1236             codeMemPoolAllocator.SetMemPool(codeMemPool);
1237         }
1238         return codeMemPool;
1239     }
1240 
SetCodeMemPool(MemPool * currCodeMemPool)1241     void SetCodeMemPool(MemPool *currCodeMemPool)
1242     {
1243         codeMemPool = currCodeMemPool;
1244     }
1245 
GetCodeMPAllocator()1246     MapleAllocator &GetCodeMPAllocator()
1247     {
1248         GetCodeMemPool();
1249         return codeMemPoolAllocator;
1250     }
1251 
AddFuncGenericDeclare(GenericDeclare * g)1252     void AddFuncGenericDeclare(GenericDeclare *g)
1253     {
1254         genericDeclare.push_back(g);
1255     }
1256 
AddFuncGenericArg(AnnotationType * a)1257     void AddFuncGenericArg(AnnotationType *a)
1258     {
1259         genericArg.push_back(a);
1260     }
1261 
AddFuncGenericRet(AnnotationType * r)1262     void AddFuncGenericRet(AnnotationType *r)
1263     {
1264         genericRet = r;
1265     }
1266 
AddFuncLocalGenericVar(const GStrIdx & str,AnnotationType * at)1267     void AddFuncLocalGenericVar(const GStrIdx &str, AnnotationType *at)
1268     {
1269         genericLocalVar[str] = at;
1270     }
1271 
GetFuncGenericDeclare()1272     MapleVector<GenericDeclare *> &GetFuncGenericDeclare()
1273     {
1274         return genericDeclare;
1275     }
1276 
GetFuncGenericArg()1277     MapleVector<AnnotationType *> &GetFuncGenericArg()
1278     {
1279         return genericArg;
1280     }
1281 
SetRetrunAttrKind(const PointerAttr kind)1282     void SetRetrunAttrKind(const PointerAttr kind)
1283     {
1284         returnKind = kind;
1285     }
1286 
GetRetrunAttrKind()1287     PointerAttr GetRetrunAttrKind() const
1288     {
1289         return returnKind;
1290     }
1291 
GetFuncGenericRet()1292     AnnotationType *GetFuncGenericRet()
1293     {
1294         return genericRet;
1295     }
1296 
GetFuncLocalGenericVar(const GStrIdx & str)1297     AnnotationType *GetFuncLocalGenericVar(const GStrIdx &str)
1298     {
1299         if (genericLocalVar.find(str) == genericLocalVar.end()) {
1300             return nullptr;
1301         }
1302         return genericLocalVar[str];
1303     }
1304 
FindStmtWithId(StmtNode * stmt,uint32 stmtId)1305     StmtNode *FindStmtWithId(StmtNode *stmt, uint32 stmtId)
1306     {
1307         while (stmt != nullptr) {
1308             StmtNode *next = stmt->GetNext();
1309             switch (stmt->GetOpCode()) {
1310                 case OP_dowhile:
1311                 case OP_while: {
1312                     WhileStmtNode *wnode = static_cast<WhileStmtNode *>(stmt);
1313                     if (wnode->GetBody() != nullptr && wnode->GetBody()->GetFirst() != nullptr) {
1314                         StmtNode *res = FindStmtWithId(wnode->GetBody()->GetFirst(), stmtId);
1315                         if (res != nullptr) {
1316                             return res;
1317                         }
1318                     }
1319                     break;
1320                 }
1321                 case OP_if: {
1322                     if (stmt->GetMeStmtID() == stmtId) {
1323                         return stmt;
1324                     }
1325                     IfStmtNode *inode = static_cast<IfStmtNode *>(stmt);
1326                     if (inode->GetThenPart() != nullptr && inode->GetThenPart()->GetFirst() != nullptr) {
1327                         StmtNode *res = FindStmtWithId(inode->GetThenPart()->GetFirst(), stmtId);
1328                         if (res != nullptr) {
1329                             return res;
1330                         }
1331                     }
1332                     if (inode->GetElsePart() != nullptr && inode->GetElsePart()->GetFirst() != nullptr) {
1333                         StmtNode *res = FindStmtWithId(inode->GetElsePart()->GetFirst(), stmtId);
1334                         if (res != nullptr) {
1335                             return res;
1336                         }
1337                     }
1338                     break;
1339                 }
1340                 case OP_callassigned:
1341                 case OP_call:
1342                 case OP_brtrue:
1343                 case OP_brfalse: {
1344                     if (stmt->GetMeStmtID() == stmtId) {
1345                         return stmt;
1346                     }
1347                     break;
1348                 }
1349                 default: {
1350                     break;
1351                 }
1352             }
1353             stmt = next;
1354         }
1355         return nullptr;
1356     }
1357 
GetStmtNodeFromMeId(uint32 stmtId)1358     StmtNode *GetStmtNodeFromMeId(uint32 stmtId)
1359     {
1360         if (GetBody() == nullptr) {
1361             return nullptr;
1362         }
1363         StmtNode *stmt = GetBody()->GetFirst();
1364         return FindStmtWithId(stmt, stmtId);
1365     }
1366 
GetCodeMemPoolTmp()1367     MemPool *GetCodeMemPoolTmp()
1368     {
1369         if (codeMemPoolTmp == nullptr) {
1370             codeMemPoolTmp = new ThreadLocalMemPool(memPoolCtrler, "func code mempool");
1371             codeMemPoolTmpAllocator.SetMemPool(codeMemPoolTmp);
1372         }
1373         return codeMemPoolTmp;
1374     }
1375 
CheckParamNullType(MIRSymbol * sym)1376     bool CheckParamNullType(MIRSymbol *sym)
1377     {
1378         return paramNonullTypeMap.find(sym) != paramNonullTypeMap.end();
1379     }
1380 
GetParamNonull(MIRSymbol * sym)1381     PointerAttr GetParamNonull(MIRSymbol *sym)
1382     {
1383         return paramNonullTypeMap[sym];
1384     }
1385 
SetParamNonull(MIRSymbol * sym,PointerAttr type)1386     void SetParamNonull(MIRSymbol *sym, PointerAttr type)
1387     {
1388         paramNonullTypeMap[sym] = type;
1389     }
1390 
CopyReferedRegs(std::set<uint32> regs)1391     void CopyReferedRegs(std::set<uint32> regs)
1392     {
1393         for (auto reg : regs) {
1394             referedPregs.insert(reg);
1395         }
1396     }
1397 
GetReferedRegs()1398     MapleSet<uint32> GetReferedRegs() const
1399     {
1400         return referedPregs;
1401     }
1402 
SetDerived2BaseRef(PregIdx deriveRef,PregIdx baseRef)1403     void SetDerived2BaseRef(PregIdx deriveRef, PregIdx baseRef)
1404     {
1405         CHECK_FATAL(derived2BaseRef.find(deriveRef) == derived2BaseRef.end(), "derived2BaseRef double set");
1406         derived2BaseRef[deriveRef] = baseRef;
1407     }
1408 
GetDerived2BaseRef()1409     const MapleUnorderedMap<PregIdx, PregIdx> &GetDerived2BaseRef() const
1410     {
1411         return derived2BaseRef;
1412     }
1413 
IsReferedRegsValid()1414     bool IsReferedRegsValid() const
1415     {
1416         return referedRegsValid;
1417     }
1418 
SetReferedRegsValid(bool val)1419     void SetReferedRegsValid(bool val)
1420     {
1421         referedRegsValid = val;
1422     }
1423 
GetFuncDesc()1424     FuncDesc &GetFuncDesc()
1425     {
1426         return funcDesc;
1427     }
1428 
SetFuncDesc(const FuncDesc & value)1429     void SetFuncDesc(const FuncDesc &value)
1430     {
1431         funcDesc = value;
1432     }
1433 
SetProfCtrTbl(MIRSymbol * pct)1434     void SetProfCtrTbl(MIRSymbol *pct)
1435     {
1436         CHECK_FATAL(Options::profileGen, "This is only for profileGen");
1437         profCtrTbl = pct;
1438     }
1439 
GetProfCtrTbl()1440     MIRSymbol *GetProfCtrTbl()
1441     {
1442         return profCtrTbl;
1443     }
1444 
SetNumCtrs(uint32 num)1445     void SetNumCtrs(uint32 num)
1446     {
1447         CHECK_FATAL(Options::profileGen, "This is only for profileGen");
1448         nCtrs = num;
1449     }
1450 
GetNumCtrs()1451     uint32 GetNumCtrs() const
1452     {
1453         return nCtrs;
1454     }
1455 
SetFileLineNoChksum(uint64 chksum)1456     void SetFileLineNoChksum(uint64 chksum)
1457     {
1458         CHECK_FATAL(Options::profileGen, "This is only for profileGen");
1459         fileLinenoChksum = chksum;
1460     }
1461 
GetFileLineNoChksum()1462     uint64 GetFileLineNoChksum() const
1463     {
1464         return fileLinenoChksum;
1465     }
1466 
SetCFGChksum(uint64 chksum)1467     void SetCFGChksum(uint64 chksum)
1468     {
1469         CHECK_FATAL(Options::profileGen, "This is only for profileGen");
1470         cfgChksum = chksum;
1471     }
1472 
GetCFGChksum()1473     uint64 GetCFGChksum() const
1474     {
1475         return cfgChksum;
1476     }
1477 
InitFuncDescToBest()1478     void InitFuncDescToBest()
1479     {
1480         funcDesc.InitToBest();
1481     }
1482 
GetFuncDesc()1483     const FuncDesc &GetFuncDesc() const
1484     {
1485         return funcDesc;
1486     }
1487 
AddProfileDesc(uint64 hash,uint32 start,uint32 end)1488     void AddProfileDesc(uint64 hash, uint32 start, uint32 end)
1489     {
1490         profileDesc = module->GetMemPool()->New<IRProfileDesc>(hash, start, end);
1491     }
1492 
GetProfInf()1493     const IRProfileDesc *GetProfInf()
1494     {
1495         if (profileDesc == nullptr) {
1496             // return profileDesc with default value
1497             profileDesc = module->GetMemPool()->New<IRProfileDesc>();
1498         }
1499         return profileDesc;
1500     }
1501 
IsVisited()1502     bool IsVisited() const
1503     {
1504         return isVisited;
1505     }
SetIsVisited()1506     void SetIsVisited()
1507     {
1508         isVisited = true;
1509     }
1510 
SetFuncProfData(GcovFuncInfo * data)1511     void SetFuncProfData(GcovFuncInfo *data)
1512     {
1513         funcProfData = data;
1514     }
GetFuncProfData()1515     GcovFuncInfo *GetFuncProfData()
1516     {
1517         return funcProfData;
1518     }
GetFuncProfData()1519     GcovFuncInfo *GetFuncProfData() const
1520     {
1521         return funcProfData;
1522     }
SetStmtFreq(uint32_t stmtID,uint64_t freq)1523     void SetStmtFreq(uint32_t stmtID, uint64_t freq)
1524     {
1525         DEBUG_ASSERT((funcProfData != nullptr && freq > 0), "nullptr check");
1526         funcProfData->SetStmtFreq(stmtID, static_cast<int64_t>(freq));
1527     }
1528 
GetFrameReseverdSlot()1529     uint8 GetFrameReseverdSlot()
1530     {
1531         return funcAttrs.GetFrameResverdSlot();
1532     }
1533 
1534 private:
1535     MIRModule *module;      // the module that owns this function
1536     PUIdx puIdx = 0;        // the PU index of this function
1537     PUIdx puIdxOrigin = 0;  // the original puIdx when initial generation
1538     StIdx symbolTableIdx;   // the symbol table index of this function
1539     int32 sccID = -1;       // the scc id of this function, for mplipa
1540     MIRFuncType *funcType = nullptr;
1541     TyIdx inferredReturnTyIdx {0};  // the actual return type of of this function (may be a
1542                                     // subclass of the above). 0 means can not be inferred.
1543     TyIdx classTyIdx {0};           // class/interface type this function belongs to
1544     MapleVector<FormalDef> formalDefVec {module->GetMPAllocator().Adapter()};  // the formals in function definition
1545     MapleSet<MIRSymbol *> retRefSym {module->GetMPAllocator().Adapter()};
1546 
1547     MapleVector<GenericDeclare *> genericDeclare {module->GetMPAllocator().Adapter()};
1548     MapleVector<AnnotationType *> genericArg {module->GetMPAllocator().Adapter()};
1549     MapleMap<GStrIdx, AnnotationType *> genericLocalVar {module->GetMPAllocator().Adapter()};
1550     AnnotationType *genericRet = nullptr;
1551 
1552     MIRSymbolTable *symTab = nullptr;
1553     MIRTypeNameTable *typeNameTab = nullptr;
1554     MIRLabelTable *labelTab = nullptr;
1555     MIRPregTable *pregTab = nullptr;
1556     MemPool *codeMemPool = nullptr;
1557     MapleAllocator codeMemPoolAllocator {nullptr};
1558     uint32 callTimes = 0;
1559     BlockNode *body = nullptr;
1560     BlockNode *bodyLast = nullptr;
1561     FuncAttrs funcAttrs {};
1562     uint32 flag = 0;
1563     uint16 hashCode = 0;   // for methodmetadata order
1564     uint32 fileIndex = 0;  // this function belongs to which file, used by VM for plugin manager
1565     MIRInfoVector info {module->GetMPAllocator().Adapter()};
1566     MapleVector<bool> infoIsString {module->GetMPAllocator().Adapter()};  // tells if an entry has string value
1567     MIRScope *scope = nullptr;
1568     MapleMap<uint32, uint32> *freqFirstMap = nullptr;  // save bb frequency in its first_stmt, key is stmtId
1569     MapleMap<uint32, uint32> *freqLastMap = nullptr;   // save bb frequency in its last_stmt, key is stmtId
1570     MapleSet<uint32> referedPregs {module->GetMPAllocator().Adapter()};
1571     MapleUnorderedMap<PregIdx, PregIdx> derived2BaseRef {module->GetMPAllocator().Adapter()};
1572     bool referedRegsValid = false;
1573     bool hasVlaOrAlloca = false;
1574     bool withLocInfo = true;
1575     bool isVisited = false;  // only used in inline phase.
1576     bool isDirty = false;
1577     bool fromMpltInline = false;  // Whether this function is imported from mplt_inline file or not.
1578     uint8_t layoutType = kLayoutUnused;
1579     uint32 frameSize = 0;
1580     uint32 upFormalSize = 0;
1581     uint32 outParmSize = 0;
1582     uint16 moduleID = 0;
1583     uint32 funcSize = 0;  // size of code in words
1584     uint32 tempCount = 0;
1585     uint8 *formalWordsTypeTagged = nullptr;  // bit vector where the Nth bit tells whether
1586     // the Nth word in the formal parameters area
1587     // addressed upward from %%FP (that means
1588     // the word at location (%%FP + N*4)) has
1589     // typetag; if yes, the typetag is the word
1590     // at (%%FP + N*4 + 4); the bitvector's size
1591     // is given by BlockSize2BitvectorSize(upFormalSize)
1592     uint8 *localWordsTypeTagged = nullptr;  // bit vector where the Nth bit tells whether
1593     // the Nth word in the local stack frame
1594     // addressed downward from %%FP (that means
1595     // the word at location (%%FP - N*4)) has
1596     // typetag; if yes, the typetag is the word
1597     // at (%%FP - N*4 + 4); the bitvector's size
1598     // is given by BlockSize2BitvectorSize(frameSize)
1599     uint8 *formalWordsRefCounted = nullptr;  // bit vector where the Nth bit tells whether
1600     // the Nth word in the formal parameters area
1601     // addressed upward from %%FP (that means
1602     // the word at location (%%FP + N*4)) points to
1603     // a dynamic memory block that needs reference
1604     // count; the bitvector's size is given by
1605     // BlockSize2BitvectorSize(upFormalSize)
1606     uint8 *localWordsRefCounted = nullptr;  // bit vector where the Nth bit tells whether
1607     // the Nth word in the local stack frame
1608     // addressed downward from %%FP (that means
1609     // the word at location (%%FP - N*4)) points to
1610     // a dynamic memory block that needs reference
1611     // count; the bitvector's size is given by
1612     // BlockSize2BitvectorSize(frameSize)
1613     // uint16 numlabels; // removed. label table size
1614     // StmtNode **lbl2stmt // lbl2stmt table, removed
1615     // to hold unmangled class and function names
1616     MeFunction *meFunc = nullptr;
1617     EAConnectionGraph *eacg = nullptr;
1618     IRProfileDesc *profileDesc = nullptr;
1619     GStrIdx baseClassStrIdx {0};  // the string table index of base class name
1620     GStrIdx baseFuncStrIdx {0};   // the string table index of base function name
1621     // the string table index of base function name mangled with type info
1622     GStrIdx baseFuncWithTypeStrIdx {0};
1623     // funcname + types of args, no type of retv
1624     GStrIdx baseFuncSigStrIdx {0};
1625     GStrIdx signatureStrIdx {0};
1626     MemPool *codeMemPoolTmp {nullptr};
1627     MapleAllocator codeMemPoolTmpAllocator {nullptr};
1628     bool useTmpMemPool = false;
1629     PointerAttr returnKind = PointerAttr::kPointerUndeiced;
1630     MapleMap<MIRSymbol *, PointerAttr> paramNonullTypeMap {module->GetMPAllocator().Adapter()};
1631     FuncDesc funcDesc {};
1632     MIRSymbol *profCtrTbl = nullptr;
1633     uint32 nCtrs = 0;  // number of counters
1634     uint64 fileLinenoChksum = 0;
1635     uint64 cfgChksum = 0;
1636     GcovFuncInfo *funcProfData = nullptr;
1637     void DumpFlavorLoweredThanMmpl() const;
1638     MIRFuncType *ReconstructFormals(const std::vector<MIRSymbol *> &symbols, bool clearOldArgs);
1639 };
1640 }  // namespace maple
1641 #endif  // MAPLE_IR_INCLUDE_MIR_FUNCTION_H
1642