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