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