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