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_MODULE_H
17 #define MAPLE_IR_INCLUDE_MIR_MODULE_H
18 #include "types_def.h"
19 #include "prim_types.h"
20 #include "intrinsics.h"
21 #include "opcodes.h"
22 #include "mpl_logging.h"
23 #include "namemangler.h"
24 #include "gcov_profile.h"
25 #include "string_utils.h"
26 #if MIR_FEATURE_FULL
27 #include <string>
28 #include <unordered_set>
29 #include <shared_mutex>
30 #include <thread>
31 #include <mutex>
32 #include <map>
33 #include "mempool.h"
34 #include "mempool_allocator.h"
35 #include "maple_string.h"
36 #endif  // MIR_FEATURE_FULL
37 
38 namespace maple {
39 class CallInfo;    // circular dependency exists, no other choice
40 class MIRModule;   // circular dependency exists, no other choice
41 class MIRBuilder;  // circular dependency exists, no other choice
42 using MIRModulePtr = MIRModule *;
43 using MIRBuilderPtr = MIRBuilder *;
44 
45 enum MIRFlavor {
46     kFlavorUnknown,
47     kFeProduced,
48     kMeProduced,
49     kBeLowered,
50     kFlavorMbc,
51     kMmpl,
52     kCmplV1,
53     kCmpl,  // == CMPLv2
54     kFlavorLmbc,
55 };
56 
57 enum MIRSrcLang {
58     kSrcLangUnknown,
59     kSrcLangC,
60     kSrcLangJs,
61     kSrcLangCPlusPlus,
62     kSrcLangChar,
63     // SrcLangSwift : when clang adds support for Swift.
64 };
65 
66 class CalleePair {
67 public:
CalleePair(PUIdx id, int32_t index)68     CalleePair(PUIdx id, int32_t index) : id(id), index(index) {}
operator <(const CalleePair &func) const69     bool operator<(const CalleePair &func) const
70     {
71         if (id < func.id)
72             return true;
73         else if (id == func.id && index < func.index) {
74             return true;
75         } else {
76             return false;
77         }
78     }
79 
80 private:
81     PUIdx id;
82     int32_t index;
83 };
84 
85 class CallerSummary {
86 public:
CallerSummary(PUIdx id, uint32 stmtId)87     CallerSummary(PUIdx id, uint32 stmtId) : id(id), stmtId(stmtId) {}
GetPuidx() const88     PUIdx GetPuidx() const
89     {
90         return id;
91     };
GetStmtId() const92     uint32 GetStmtId() const
93     {
94         return stmtId;
95     }
96 
97 private:
98     PUIdx id;
99     uint32 stmtId;
100 };
101 
102 // This data structure is for the ipa-cp. Important expresstion is about the condtion statement.
103 class ImpExpr {
104 public:
ImpExpr(uint32 stmtId, uint32 paramIndex)105     ImpExpr(uint32 stmtId, uint32 paramIndex) : stmtId(stmtId), paramIndex(paramIndex) {}
GetStmtId() const106     uint32 GetStmtId() const
107     {
108         return stmtId;
109     }
GetParamIndex() const110     uint32 GetParamIndex() const
111     {
112         return paramIndex;
113     }
114 
115 private:
116     uint32 stmtId;
117     uint32 paramIndex;
118 };
119 
120 // blksize gives the size of the memory block in bytes; there are (blksize+3)/4
121 // words; 1 bit for each word, so the bit vector's length in bytes is
122 // ((blksize+3)/4+7)/8
BlockSize2BitVectorSize(uint32 blkSize)123 static inline uint32 BlockSize2BitVectorSize(uint32 blkSize)
124 {
125     uint32 bitVectorLen = ((blkSize + 3) / 4 + 7) / 8; // the bit vector's length in bytes is ((blksize+3)/4+7)/8
126     constexpr uint32 kRoundUp2Bit = 0xfffffffc;        // 11111111111111111111111111111100
127     return (bitVectorLen + 3) & kRoundUp2Bit;  // add 3 and round up to word boundary
128 }
129 
130 #if MIR_FEATURE_FULL
131 class MIRType;            // circular dependency exists, no other choice
132 class MIRFunction;        // circular dependency exists, no other choice
133 class MIRSymbol;          // circular dependency exists, no other choice
134 class MIRSymbolTable;     // circular dependency exists, no other choice
135 class MIRFloatConst;      // circular dependency exists, no other choice
136 class MIRDoubleConst;     // circular dependency exists, no other choice
137 class MIRBuilder;         // circular dependency exists, no other choice
138 class DebugInfo;          // circular dependency exists, no other choice
139 class EAConnectionGraph;  // circular dependency exists, no other choice
140 using MIRInfoPair = std::pair<GStrIdx, uint32>;
141 using MIRInfoVector = MapleVector<MIRInfoPair>;
142 using MIRDataPair = std::pair<GStrIdx, std::vector<uint8>>;
143 using MIRDataVector = MapleVector<MIRDataPair>;
144 constexpr int kMaxEncodedValueLen = 10;
145 struct EncodedValue {
146     uint8 encodedValue[kMaxEncodedValueLen] = {0};
147 };
148 
149 class MIRTypeNameTable {
150 public:
MIRTypeNameTable(MapleAllocator &allocator)151     explicit MIRTypeNameTable(MapleAllocator &allocator) : gStrIdxToTyIdxMap(std::less<GStrIdx>(), allocator.Adapter())
152     {
153     }
154 
155     ~MIRTypeNameTable() = default;
156 
GetGStrIdxToTyIdxMap() const157     const MapleMap<GStrIdx, TyIdx> &GetGStrIdxToTyIdxMap() const
158     {
159         return gStrIdxToTyIdxMap;
160     }
161 
GetTyIdxFromGStrIdx(GStrIdx idx) const162     TyIdx GetTyIdxFromGStrIdx(GStrIdx idx) const
163     {
164         auto it = gStrIdxToTyIdxMap.find(idx);
165         if (it == gStrIdxToTyIdxMap.end()) {
166             return TyIdx(0);
167         }
168         return it->second;
169     }
170 
SetGStrIdxToTyIdx(GStrIdx gStrIdx, TyIdx tyIdx)171     void SetGStrIdxToTyIdx(GStrIdx gStrIdx, TyIdx tyIdx)
172     {
173         gStrIdxToTyIdxMap[gStrIdx] = tyIdx;
174     }
175 
Size() const176     size_t Size() const
177     {
178         return gStrIdxToTyIdxMap.size();
179     }
180 
181 private:
182     MapleMap<GStrIdx, TyIdx> gStrIdxToTyIdxMap;
183 };
184 
185 class MIRModule {
186 public:
187     bool firstInline = true;
188     using CallSite = std::pair<CallInfo *, PUIdx>;
189 
190     explicit MIRModule(const std::string &fn = "");
191     MIRModule(MIRModule &p) = delete;
192     MIRModule &operator=(const MIRModule &module) = delete;
193     ~MIRModule();
194 
GetMemPool() const195     MemPool *GetMemPool() const
196     {
197         return memPool;
198     }
GetPragmaMemPool()199     MemPool *GetPragmaMemPool()
200     {
201         return pragmaMemPool;
202     }
GetPragmaMPAllocator()203     MapleAllocator &GetPragmaMPAllocator()
204     {
205         return pragmaMemPoolAllocator;
206     }
GetMPAllocator() const207     const MapleAllocator &GetMPAllocator() const
208     {
209         return memPoolAllocator;
210     }
211 
ReleasePragmaMemPool()212     void ReleasePragmaMemPool()
213     {
214         if (pragmaMemPool) {
215             memPoolCtrler.DeleteMemPool(pragmaMemPool);
216         }
217         pragmaMemPool = nullptr;
218     }
219 
GetMPAllocator()220     MapleAllocator &GetMPAllocator()
221     {
222         return memPoolAllocator;
223     }
224 
GetFunctionList() const225     const auto &GetFunctionList() const
226     {
227         return functionList;
228     }
GetFunctionList()229     auto &GetFunctionList()
230     {
231         return functionList;
232     }
233 
GetImportedMplt() const234     const MapleVector<std::string> &GetImportedMplt() const
235     {
236         return importedMplt;
237     }
PushbackImportedMplt(const std::string &importFileName)238     void PushbackImportedMplt(const std::string &importFileName)
239     {
240         importedMplt.push_back(importFileName);
241     }
242 
GetTypeNameTab()243     MIRTypeNameTable *GetTypeNameTab()
244     {
245         return typeNameTab;
246     }
247 
GetTypeDefOrder() const248     const MapleVector<GStrIdx> &GetTypeDefOrder() const
249     {
250         return typeDefOrder;
251     }
PushbackTypeDefOrder(GStrIdx gstrIdx)252     void PushbackTypeDefOrder(GStrIdx gstrIdx)
253     {
254         typeDefOrder.push_back(gstrIdx);
255     }
256 
SetCurFunction(MIRFunction *f)257     void SetCurFunction(MIRFunction *f)
258     {
259         curFunction = f;
260     }
261 
GetSrcLang() const262     MIRSrcLang GetSrcLang() const
263     {
264         return srcLang;
265     }
266 
GetSymbolSet() const267     const MapleSet<StIdx> &GetSymbolSet() const
268     {
269         return symbolSet;
270     }
271 
GetSymbolDefOrder() const272     const MapleVector<StIdx> &GetSymbolDefOrder() const
273     {
274         return symbolDefOrder;
275     }
276 
GetGcovProfile()277     GcovProfileData *GetGcovProfile()
278     {
279         return gcovProfile;
280     }
SetGcovProfile(GcovProfileData *info)281     void SetGcovProfile(GcovProfileData *info)
282     {
283         gcovProfile = info;
284     }
285 
SetSomeSymbolNeedForDecl(bool s)286     void SetSomeSymbolNeedForDecl(bool s)
287     {
288         someSymbolNeedForwDecl = s;
289     }
290 
CurFunction() const291     MIRFunction *CurFunction() const
292     {
293         return curFunction;
294     }
295 
296     MemPool *CurFuncCodeMemPool() const;
297     MapleAllocator *CurFuncCodeMemPoolAllocator() const;
298     MapleAllocator &GetCurFuncCodeMPAllocator() const;
299     void AddExternStructType(TyIdx tyIdx);
300     void AddExternStructType(const MIRType *t);
301     void AddSymbol(StIdx stIdx);
302     void AddSymbol(const MIRSymbol *s);
AddFunction(MIRFunction *pf)303     void AddFunction(MIRFunction *pf)
304     {
305         functionList.push_back(pf);
306     }
307 
308 #ifdef ARK_LITECG_DEBUG
309     void DumpGlobals(bool emitStructureType = true) const;
310     void Dump(bool emitStructureType = true, const std::unordered_set<std::string> *dumpFuncSet = nullptr) const;
311     void DumpToFile(const std::string &fileNameStr, bool emitStructureType = true) const;
312     void DumpInlineCandidateToFile(const std::string &fileNameStr);
313     void DumpDefType();
314 #endif
315 #ifdef ARK_LITECG_DEBUG
316     void DumpClassToFile(const std::string &path) const;
317     void DumpFunctionList(const std::unordered_set<std::string> *dumpFuncSet) const;
318     void DumpGlobalArraySymbol() const;
319 #endif
320 
321     void Emit(const std::string &outFileName) const;
GetAndIncFloatNum()322     uint32 GetAndIncFloatNum()
323     {
324         return floatNum++;
325     }
326 
SetEntryFunction(MIRFunction *f)327     void SetEntryFunction(MIRFunction *f)
328     {
329         entryFunc = f;
330     }
331 
GetEntryFunction() const332     MIRFunction *GetEntryFunction() const
333     {
334         return entryFunc;
335     }
336 
337     uint32 GetFileinfo(GStrIdx strIdx) const;
338     void OutputFunctionListAsciiMpl(const std::string &phaseName);
GetFileName() const339     const std::string &GetFileName() const
340     {
341         return fileName;
342     }
343 
GetFileText() const344     const std::string &GetFileText() const
345     {
346         return fileText;
347     }
348 
IsNeedFile() const349     bool IsNeedFile() const
350     {
351         return needFile;
352     }
353 
354 #ifdef ARK_LITECG_DEBUG
355     std::string GetFileNameAsPostfix() const;
356 #endif
SetFileName(const std::string &name)357     void SetFileName(const std::string &name)
358     {
359         fileName = name;
360     }
361 
GetProfileDataFileName() const362     std::string GetProfileDataFileName() const
363     {
364         std::string profileDataFileName = fileName.substr(0, fileName.find_last_of("."));
365         std::replace(profileDataFileName.begin(), profileDataFileName.end(), '.', '_');
366         std::replace(profileDataFileName.begin(), profileDataFileName.end(), '-', '_');
367         std::replace(profileDataFileName.begin(), profileDataFileName.end(), '/', '_');
368         profileDataFileName = profileDataFileName + namemangler::kProfFileNameExt;
369         return profileDataFileName;
370     }
371 
IsCModule() const372     bool IsCModule() const
373     {
374         return srcLang == kSrcLangC || srcLang == kSrcLangCPlusPlus;
375     }
376 
IsCPlusPlusModule() const377     bool IsCPlusPlusModule() const
378     {
379         return srcLang == kSrcLangCPlusPlus;
380     }
381 
IsCharModule() const382     bool IsCharModule() const
383     {
384         return srcLang == kSrcLangChar;
385     }
386 
addSuperCall(const std::string &func)387     void addSuperCall(const std::string &func)
388     {
389         (void)superCallSet.insert(func);
390     }
391 
findSuperCall(const std::string &func) const392     bool findSuperCall(const std::string &func) const
393     {
394         return superCallSet.find(func) != superCallSet.end();
395     }
396 
SetUseFuncCodeMemPoolTmp()397     void SetUseFuncCodeMemPoolTmp()
398     {
399         useFuncCodeMemPoolTmp = true;
400     }
401 
ResetUseFuncCodeMemPoolTmp()402     void ResetUseFuncCodeMemPoolTmp()
403     {
404         useFuncCodeMemPoolTmp = false;
405     }
406 
GetOptFuncsSize() const407     size_t GetOptFuncsSize() const
408     {
409         return optimizedFuncs.size();
410     }
411 
AddOptFuncs(MIRFunction *func)412     void AddOptFuncs(MIRFunction *func)
413     {
414         optimizedFuncs.emplace(func);
415     }
416 
GetOptFuncs() const417     const MapleSet<MIRFunction *> &GetOptFuncs() const
418     {
419         return optimizedFuncs;
420     }
421 
IsOptFunc(MIRFunction *func) const422     bool IsOptFunc(MIRFunction *func) const
423     {
424         if (std::find(optimizedFuncs.begin(), optimizedFuncs.end(), func) != optimizedFuncs.end()) {
425             return true;
426         }
427         return false;
428     }
429 
AddOptFuncsType(MIRType *type)430     void AddOptFuncsType(MIRType *type)
431     {
432         optimizedFuncsType.emplace(type);
433     }
434 
GetPuIdxFieldInitializedMap() const435     const MapleMap<PUIdx, MapleSet<FieldID> *> &GetPuIdxFieldInitializedMap() const
436     {
437         std::shared_lock<std::shared_timed_mutex> lock(fieldMapMutex);
438         return puIdxFieldInitializedMap;
439     }
SetPuIdxFieldSet(PUIdx puIdx, MapleSet<FieldID> *fieldIDSet)440     void SetPuIdxFieldSet(PUIdx puIdx, MapleSet<FieldID> *fieldIDSet)
441     {
442         std::unique_lock<std::shared_timed_mutex> lock(fieldMapMutex);
443         puIdxFieldInitializedMap[puIdx] = fieldIDSet;
444     }
445 
GetCalleeParamAboutInt()446     std::map<CalleePair, std::map<int64_t, std::vector<CallerSummary>>> &GetCalleeParamAboutInt()
447     {
448         return calleeParamAboutInt;
449     }
450 
GetCalleeParamAboutFloat()451     std::map<CalleePair, std::map<float, std::vector<CallerSummary>>> &GetCalleeParamAboutFloat()
452     {
453         return calleeParamAboutFloat;
454     }
455 
GetCalleeParamAboutDouble()456     std::map<CalleePair, std::map<double, std::vector<CallerSummary>>> &GetCalleeParamAboutDouble()
457     {
458         return calleeParamAboutDouble;
459     }
460 
GetFuncImportantExpr()461     std::map<PUIdx, std::vector<ImpExpr>> &GetFuncImportantExpr()
462     {
463         return funcImportantExpr;
464     }
465 
GetRealCaller() const466     const auto &GetRealCaller() const
467     {
468         return realCaller;
469     }
470 
GetRealCaller()471     auto &GetRealCaller()
472     {
473         return realCaller;
474     }
475 
GetInlineGlobals() const476     const MapleSet<uint32_t> &GetInlineGlobals() const
477     {
478         return inliningGlobals;
479     }
InsertInlineGlobal(uint32_t global)480     void InsertInlineGlobal(uint32_t global)
481     {
482         (void)inliningGlobals.insert(global);
483     }
484 
GetPUIdxFieldInitializedMapItem(PUIdx key) const485     const MapleSet<FieldID> *GetPUIdxFieldInitializedMapItem(PUIdx key) const
486     {
487         std::shared_lock<std::shared_timed_mutex> lock(fieldMapMutex);
488         auto it = puIdxFieldInitializedMap.find(key);
489         if (it != puIdxFieldInitializedMap.end()) {
490             return it->second;
491         }
492         return nullptr;
493     }
494 
GetOut() const495     std::ostream &GetOut() const
496     {
497         return out;
498     }
499 
GetMIRBuilder() const500     const MIRBuilderPtr &GetMIRBuilder() const
501     {
502         return mirBuilder;
503     }
504 
GetEntryFuncName() const505     const std::string &GetEntryFuncName() const
506     {
507         return entryFuncName;
508     }
SetEntryFuncName(const std::string &entryFunctionName)509     void SetEntryFuncName(const std::string &entryFunctionName)
510     {
511         entryFuncName = entryFunctionName;
512     }
513 
GetThrowableTyIdx() const514     TyIdx GetThrowableTyIdx() const
515     {
516         return throwableTyIdx;
517     }
SetThrowableTyIdx(TyIdx throwableTypeIndex)518     void SetThrowableTyIdx(TyIdx throwableTypeIndex)
519     {
520         throwableTyIdx = throwableTypeIndex;
521     }
522 
GetWithProfileInfo() const523     bool GetWithProfileInfo() const
524     {
525         return withProfileInfo;
526     }
SetWithProfileInfo(bool withProfInfo)527     void SetWithProfileInfo(bool withProfInfo)
528     {
529         withProfileInfo = withProfInfo;
530     }
531 
IsInIPA() const532     bool IsInIPA() const
533     {
534         return inIPA;
535     }
IsWithMe() const536     bool IsWithMe() const
537     {
538         return withMe;
539     }
SetWithMe(bool isWithMe)540     void SetWithMe(bool isWithMe)
541     {
542         withMe = isWithMe;
543     }
SetInIPA(bool isInIPA)544     void SetInIPA(bool isInIPA)
545     {
546         inIPA = isInIPA;
547     }
548 
SetFileText(const std::string &inText)549     void SetFileText(const std::string &inText)
550     {
551         fileText = inText;
552         needFile = false;
553     }
554 
GetFileInfo()555     MIRInfoVector &GetFileInfo()
556     {
557         return fileInfo;
558     }
PushFileInfoPair(MIRInfoPair pair)559     void PushFileInfoPair(MIRInfoPair pair)
560     {
561         fileInfo.push_back(pair);
562     }
SetFileInfo(const MIRInfoVector &fileInf)563     void SetFileInfo(const MIRInfoVector &fileInf)
564     {
565         fileInfo = fileInf;
566     }
567 
GetFileInfoIsString()568     MapleVector<bool> &GetFileInfoIsString()
569     {
570         return fileInfoIsString;
571     }
SetFileInfoIsString(const MapleVector<bool> &fileInfoIsStr)572     void SetFileInfoIsString(const MapleVector<bool> &fileInfoIsStr)
573     {
574         fileInfoIsString = fileInfoIsStr;
575     }
PushFileInfoIsString(bool isString)576     void PushFileInfoIsString(bool isString)
577     {
578         fileInfoIsString.push_back(isString);
579     }
580 
GetFileData() const581     const MIRDataVector &GetFileData() const
582     {
583         return fileData;
584     }
PushbackFileData(const MIRDataPair &pair)585     void PushbackFileData(const MIRDataPair &pair)
586     {
587         fileData.push_back(pair);
588     }
589 
GetSrcFileInfo() const590     const MIRInfoVector &GetSrcFileInfo() const
591     {
592         return srcFileInfo;
593     }
PushbackFileInfo(const MIRInfoPair &pair)594     void PushbackFileInfo(const MIRInfoPair &pair)
595     {
596         srcFileInfo.push_back(pair);
597     }
598 
GetFlavor() const599     const MIRFlavor &GetFlavor() const
600     {
601         return flavor;
602     }
SetFlavor(MIRFlavor flv)603     void SetFlavor(MIRFlavor flv)
604     {
605         flavor = flv;
606     }
607 
SetSrcLang(MIRSrcLang sourceLanguage)608     void SetSrcLang(MIRSrcLang sourceLanguage)
609     {
610         srcLang = sourceLanguage;
611     }
612 
GetID() const613     uint16 GetID() const
614     {
615         return id;
616     }
617 
SetID(uint16 num)618     void SetID(uint16 num)
619     {
620         id = num;
621     }
622 
GetGlobalMemSize() const623     uint32 GetGlobalMemSize() const
624     {
625         return globalMemSize;
626     }
SetGlobalMemSize(uint32 globalMemberSize)627     void SetGlobalMemSize(uint32 globalMemberSize)
628     {
629         globalMemSize = globalMemberSize;
630     }
631 
GetGlobalBlockMap()632     uint8 *GetGlobalBlockMap()
633     {
634         return globalBlkMap;
635     }
SetGlobalBlockMap(uint8 *globalBlockMap)636     void SetGlobalBlockMap(uint8 *globalBlockMap)
637     {
638         globalBlkMap = globalBlockMap;
639     }
640 
GetGlobalWordsTypeTagged()641     uint8 *GetGlobalWordsTypeTagged()
642     {
643         return globalWordsTypeTagged;
644     }
SetGlobalWordsTypeTagged(uint8 *globalWordsTyTagged)645     void SetGlobalWordsTypeTagged(uint8 *globalWordsTyTagged)
646     {
647         globalWordsTypeTagged = globalWordsTyTagged;
648     }
649 
GetGlobalWordsRefCounted()650     uint8 *GetGlobalWordsRefCounted()
651     {
652         return globalWordsRefCounted;
653     }
SetGlobalWordsRefCounted(uint8 *counted)654     void SetGlobalWordsRefCounted(uint8 *counted)
655     {
656         globalWordsRefCounted = counted;
657     }
658 
GetNumFuncs() const659     uint32 GetNumFuncs() const
660     {
661         return numFuncs;
662     }
663 
SetNumFuncs(uint32 numFunc)664     void SetNumFuncs(uint32 numFunc)
665     {
666         numFuncs = numFunc;
667     }
668 
GetImportFiles()669     MapleVector<GStrIdx> &GetImportFiles()
670     {
671         return importFiles;
672     }
673 
PushbackImportPath(GStrIdx path)674     void PushbackImportPath(GStrIdx path)
675     {
676         importPaths.push_back(path);
677     }
678 
GetAsmDecls()679     MapleVector<MapleString> &GetAsmDecls()
680     {
681         return asmDecls;
682     }
683 
GetClassList() const684     const MapleSet<uint32> &GetClassList() const
685     {
686         return classList;
687     }
688 
GetMethod2TargetMap() const689     const std::map<PUIdx, std::vector<CallInfo *>> &GetMethod2TargetMap() const
690     {
691         return method2TargetMap;
692     }
693 
GetMemFromMethod2TargetMap(PUIdx methodPuIdx)694     std::vector<CallInfo *> &GetMemFromMethod2TargetMap(PUIdx methodPuIdx)
695     {
696         return method2TargetMap[methodPuIdx];
697     }
698 
SetMethod2TargetMap(const std::map<PUIdx, std::vector<CallInfo *>> &map)699     void SetMethod2TargetMap(const std::map<PUIdx, std::vector<CallInfo *>> &map)
700     {
701         method2TargetMap = map;
702     }
703 
AddMemToMethod2TargetMap(PUIdx idx, const std::vector<CallInfo *> &callSite)704     void AddMemToMethod2TargetMap(PUIdx idx, const std::vector<CallInfo *> &callSite)
705     {
706         method2TargetMap[idx] = callSite;
707     }
708 
HasTargetHash(PUIdx idx, uint32 key) const709     bool HasTargetHash(PUIdx idx, uint32 key) const
710     {
711         auto it = method2TargetHash.find(idx);
712         if (it == method2TargetHash.end()) {
713             return false;
714         }
715         return it->second.find(key) != it->second.end();
716     }
InsertTargetHash(PUIdx idx, uint32 key)717     void InsertTargetHash(PUIdx idx, uint32 key)
718     {
719         (void)method2TargetHash[idx].insert(key);
720     }
AddValueToMethod2TargetHash(PUIdx idx, const std::unordered_set<uint32> &value)721     void AddValueToMethod2TargetHash(PUIdx idx, const std::unordered_set<uint32> &value)
722     {
723         method2TargetHash[idx] = value;
724     }
725 
GetEASummary() const726     const std::map<GStrIdx, EAConnectionGraph *> &GetEASummary() const
727     {
728         return eaSummary;
729     }
SetEAConnectionGraph(GStrIdx funcNameIdx, EAConnectionGraph *eaCg)730     void SetEAConnectionGraph(GStrIdx funcNameIdx, EAConnectionGraph *eaCg)
731     {
732         eaSummary[funcNameIdx] = eaCg;
733     }
734 
IsWithDbgInfo() const735     bool IsWithDbgInfo() const
736     {
737         return withDbgInfo;
738     }
739 
HasPartO2List() const740     bool HasPartO2List() const
741     {
742         return hasPartO2List;
743     }
744 
SetHasPartO2List(bool value)745     void SetHasPartO2List(bool value)
746     {
747         hasPartO2List = value;
748     }
749 
IsInPartO2List(const GStrIdx &idx) const750     bool IsInPartO2List(const GStrIdx &idx) const
751     {
752         return partO2FuncList.count(idx) > 0;
753     }
754 
SetBaseName(const std::string &curbaseName)755     void SetBaseName(const std::string &curbaseName)
756     {
757         baseName = curbaseName;
758     }
GetBaseName() const759     const std::string &GetBaseName() const
760     {
761         return baseName;
762     }
SetOutputFileName(const std::string &curOFileName)763     void SetOutputFileName(const std::string &curOFileName)
764     {
765         outputFileName = curOFileName;
766     }
GetOutputFileName() const767     const std::string &GetOutputFileName() const
768     {
769         return outputFileName;
770     }
SetInputFileName(const std::string &curInFileName)771     void SetInputFileName(const std::string &curInFileName)
772     {
773         inputFileName = curInFileName;
774     }
GetInputFileName() const775     const std::string &GetInputFileName() const
776     {
777         return inputFileName;
778     }
779 
GetUniqueID() const780     uint32 GetUniqueID() const
781     {
782         return UINT_MAX;
783     }
784 
SetCurModulePC(uint32 pc)785     void SetCurModulePC(uint32 pc)
786     {
787         curModulePC = pc;
788     }
789 
GetCurModulePC() const790     uint32 GetCurModulePC() const
791     {
792         return curModulePC;
793     }
794 
SetLastModulePC(uint32 pc)795     void SetLastModulePC(uint32 pc)
796     {
797         lastModulePC = pc;
798     }
799 
GetLastModulePC() const800     uint32 GetLastModulePC() const
801     {
802         return lastModulePC;
803     }
804 
SetIsAArch64(bool isAArch)805     void SetIsAArch64(bool isAArch)
806     {
807         isAArch64 = isAArch;
808     }
809 
IsAArch64() const810     bool IsAArch64() const
811     {
812         return isAArch64;
813     }
814 
815 private:
816     MemPool *memPool;
817     MemPool *pragmaMemPool;
818     MapleAllocator memPoolAllocator;
819     MapleAllocator pragmaMemPoolAllocator;
820     MapleList<MIRFunction *> functionList;  // function table in the order of the appearance of function bodies; it
821     // excludes prototype-only functions
822     MapleVector<std::string> importedMplt;
823     MIRTypeNameTable *typeNameTab;
824     MapleVector<GStrIdx> typeDefOrder;
825 
826     MapleSet<TyIdx> externStructTypeSet;
827     MapleSet<StIdx> symbolSet;
828     MapleVector<StIdx> symbolDefOrder;
829     GcovProfileData *gcovProfile;
830     bool someSymbolNeedForwDecl = false;  // some symbols' addressses used in initialization
831 
832     std::ostream &out;
833     MIRBuilder *mirBuilder;
834     std::string entryFuncName = "";  // name of the entry function
835     std::string fileName;
836     std::string fileText;
837     bool needFile = true;
838     TyIdx throwableTyIdx {0};
839     bool withProfileInfo = false;
840 
841     bool withDbgInfo = false;
842     bool inIPA = false;
843     bool withMe = true;
844     MIRInfoVector fileInfo;              // store info provided under fileInfo keyword
845     MapleVector<bool> fileInfoIsString;  // tells if an entry has string value
846     MIRDataVector fileData;
847     MIRInfoVector srcFileInfo;  // store info provided under srcFileInfo keyword
848     MIRFlavor flavor = kFlavorUnknown;
849     MIRSrcLang srcLang = kSrcLangUnknown;  // the source language
850     uint16 id = 0xffff;
851     uint32 globalMemSize = 0;       // size of storage space for all global variables
852     uint8 *globalBlkMap = nullptr;  // the memory map of the block containing all the
853     // globals, for specifying static initializations
854     uint8 *globalWordsTypeTagged = nullptr;  // bit vector where the Nth bit tells whether
855     // the Nth word in globalBlkMap has typetag;
856     // if yes, the typetag is the N+1th word; the
857     // bitvector's size is given by
858     // BlockSize2BitvectorSize(globalMemSize)
859     uint8 *globalWordsRefCounted = nullptr;  // bit vector where the Nth bit tells whether
860     // the Nth word points to a reference-counted
861     // dynamic memory block; the bitvector's size
862     // is given by BlockSize2BitvectorSize(globalMemSize)
863     uint32 numFuncs = 0;  // because puIdx 0 is reserved, numFuncs is also the highest puIdx
864     MapleVector<GStrIdx> importFiles;
865     MapleVector<GStrIdx> importPaths;
866     MapleVector<MapleString> asmDecls;
867     MapleSet<uint32> classList;
868 
869     std::map<PUIdx, std::vector<CallInfo *>> method2TargetMap;
870     std::map<PUIdx, std::unordered_set<uint32>> method2TargetHash;
871     std::map<GStrIdx, EAConnectionGraph *> eaSummary;
872 
873     bool useFuncCodeMemPoolTmp = false;
874     MIRFunction *entryFunc = nullptr;
875     uint32 floatNum = 0;
876     // curFunction for single thread, curFunctionMap for multiple threads
877     std::map<std::thread::id, MIRFunction *> curFunctionMap;
878     mutable std::mutex curFunctionMutex;
879     MIRFunction *curFunction;
880     MapleSet<MIRFunction *> optimizedFuncs;
881     MapleSet<MIRType *> optimizedFuncsType;
882     // Add the field for decouple optimization
883     std::unordered_set<std::string> superCallSet;
884     // record all the fields that are initialized in the constructor. module scope,
885     // if puIdx doesn't appear in this map, it writes to all field id
886     // if puIdx appears in the map, but it's corresponding MapleSet is nullptr, it writes nothing fieldID
887     // if puIdx appears in the map, and the value of first corresponding MapleSet is 0, the puIdx appears in this module
888     // and writes to all field id otherwise, it writes the field ids in MapleSet
889     MapleMap<PUIdx, MapleSet<FieldID> *> puIdxFieldInitializedMap;
890     mutable std::shared_timed_mutex fieldMapMutex;
891     std::map<std::pair<GStrIdx, GStrIdx>, GStrIdx> realCaller;
892     MapleSet<uint32_t> inliningGlobals;  // global symbols accessed, used for inlining
893     bool hasPartO2List = false;
894     MapleSet<GStrIdx> partO2FuncList;
895     std::string inputFileName = "";
896     std::string baseName = "";
897     std::string outputFileName = "";
898     MapleMap<uint32, MapleSet<uint32>> safetyWarningMap;  // <postion, stmt original id> indexed map for large module.
899     std::map<CalleePair, std::map<int64_t, std::vector<CallerSummary>>> calleeParamAboutInt;
900     std::map<CalleePair, std::map<double, std::vector<CallerSummary>>> calleeParamAboutDouble;
901     std::map<CalleePair, std::map<float, std::vector<CallerSummary>>> calleeParamAboutFloat;
902     std::map<PUIdx, std::vector<ImpExpr>> funcImportantExpr;
903     uint32 lastModulePC = 0;
904     uint32 curModulePC = 0;
905     bool isAArch64 = false;
906 };
907 #endif  // MIR_FEATURE_FULL
908 }  // namespace maple
909 #endif  // MAPLE_IR_INCLUDE_MIR_MODULE_H
910