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