• 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 MAPLEIPA_INCLUDE_ESCAPEANALYSIS_H
17 #define MAPLEIPA_INCLUDE_ESCAPEANALYSIS_H
18 #include <fstream>
19 #include <iostream>
20 #include <stdlib.h>
21 #include "call_graph.h"
22 #include "me_ir.h"
23 #include "irmap.h"
24 
25 namespace maple {
26 enum NodeKind { kObejectNode, kReferenceNode, kActualNode, kFieldNode, kPointerNode };
27 
28 enum EAStatus { kNoEscape, kReturnEscape, kArgumentEscape, kGlobalEscape };
29 
EscapeName(EAStatus esc)30 const inline std::string EscapeName(EAStatus esc)
31 {
32     switch (esc) {
33         case kNoEscape:
34             return "NoEsc";
35         case kReturnEscape:
36             return "RetEsc";
37         case kArgumentEscape:
38             return "ArgEsc";
39         case kGlobalEscape:
40             return "GlobalEsc";
41         default:
42             return "";
43     }
44 }
45 
46 class Location {
47 public:
Location(const std::string & modName,uint32 fileId,uint32 lineId)48     Location(const std::string &modName, uint32 fileId, uint32 lineId)
49         : modName(modName), fileId(fileId), lineId(lineId) {};
50     ~Location() = default;
51 
GetModName()52     const std::string &GetModName() const
53     {
54         return modName;
55     }
56 
GetFileId()57     uint32 GetFileId() const
58     {
59         return fileId;
60     }
61 
GetLineId()62     uint32 GetLineId() const
63     {
64         return lineId;
65     }
66 
67 private:
68     std::string modName;
69     uint32 fileId;
70     uint32 lineId;
71 };
72 
73 class EACGBaseNode;
74 class EACGObjectNode;
75 class EACGFieldNode;
76 class EACGRefNode;
77 class EACGActualNode;
78 class EACGPointerNode;
79 
80 class EAConnectionGraph {
81 public:
82     friend class BinaryMplExport;
83     friend class BinaryMplImport;
84     friend class EACGBaseNode;
85     friend class EACGObjectNode;
86     friend class EACGFieldNode;
87     friend class EACGRefNode;
88     friend class EACGPointerNode;
89     // If import is false, need init globalNode.
90     EAConnectionGraph(MIRModule *m, MapleAllocator *allocator, const GStrIdx &funcName, bool import = false)
mirModule(m)91         : mirModule(m),
92           alloc(allocator),
93           nodes(allocator->Adapter()),
94           expr2Nodes(allocator->Adapter()),
95           funcArgNodes(allocator->Adapter()),
96           callSite2Nodes(allocator->Adapter()),
97           funcStIdx(funcName),
98           hasUpdated(false),
99           needConv(false),
100           imported(import),
101           exprIdMax(0),
102           globalObj(nullptr),
103           globalRef(nullptr),
104           globalField(nullptr) {};
105     ~EAConnectionGraph() = default;
106 
107     EACGObjectNode *CreateObjectNode(MeExpr *expr, EAStatus initialEas, bool isPh, TyIdx tyIdx);
108     EACGRefNode *CreateReferenceNode(MeExpr *expr, EAStatus initialEas, bool isStatic);
109     EACGActualNode *CreateActualNode(EAStatus initialEas, bool isReurtn, bool isPh, uint8 argIdx, uint32 callSiteInfo);
110     EACGFieldNode *CreateFieldNode(MeExpr *expr, EAStatus initialEas, FieldID fId, EACGObjectNode *belongTo, bool isPh);
111     EACGPointerNode *CreatePointerNode(MeExpr *expr, EAStatus initialEas, int inderictL);
112     EACGBaseNode *GetCGNodeFromExpr(MeExpr *me);
113     EACGFieldNode *GetOrCreateFieldNodeFromIdx(EACGObjectNode &obj, int32 fieldID);
114     EACGActualNode *GetReturnNode() const;
115     const MapleVector<EACGBaseNode *> *GetFuncArgNodeVector() const;
116     void TouchCallSite(uint32 callSiteInfo);
117     MapleVector<EACGBaseNode *> *GetCallSiteArgNodeVector(uint32 callSite);
118     bool ExprCanBeOptimized(MeExpr &expr);
119 
CGHasUpdated()120     bool CGHasUpdated() const
121     {
122         return hasUpdated;
123     }
124 
UnSetCGUpdateFlag()125     void UnSetCGUpdateFlag()
126     {
127         hasUpdated = false;
128     }
129 
SetCGHasUpdated()130     void SetCGHasUpdated()
131     {
132         hasUpdated = true;
133     }
134 
SetExprIdMax(int max)135     void SetExprIdMax(int max)
136     {
137         exprIdMax = max;
138     }
139 
SetNeedConservation()140     void SetNeedConservation()
141     {
142         needConv = true;
143     }
144 
GetNeedConservation()145     bool GetNeedConservation() const
146     {
147         return needConv;
148     }
149 
GetFuncNameStrIdx()150     GStrIdx GetFuncNameStrIdx() const
151     {
152         return funcStIdx;
153     }
154 
GetGlobalObject()155     EACGObjectNode *GetGlobalObject()
156     {
157         return globalObj;
158     }
159 
GetGlobalObject()160     const EACGObjectNode *GetGlobalObject() const
161     {
162         return globalObj;
163     }
164 
GetGlobalReference()165     EACGRefNode *GetGlobalReference()
166     {
167         return globalRef;
168     }
169 
GetGlobalReference()170     const EACGRefNode *GetGlobalReference() const
171     {
172         return globalRef;
173     }
174 
GetNodes()175     const MapleVector<EACGBaseNode *> &GetNodes() const
176     {
177         return nodes;
178     }
179 
ResizeNodes(size_t size,EACGBaseNode * val)180     void ResizeNodes(size_t size, EACGBaseNode *val)
181     {
182         nodes.resize(size, val);
183     }
184 
GetNode(uint32 idx)185     EACGBaseNode *GetNode(uint32 idx) const
186     {
187         CHECK_FATAL(idx < nodes.size(), "array check fail");
188         return nodes[idx];
189     }
190 
SetNodeAt(size_t index,EACGBaseNode * val)191     void SetNodeAt(size_t index, EACGBaseNode *val)
192     {
193         nodes[index] = val;
194     }
195 
GetFuncArgNodes()196     const MapleVector<EACGBaseNode *> &GetFuncArgNodes() const
197     {
198         return funcArgNodes;
199     }
200 
GetCallSite2Nodes()201     const MapleMap<uint32, MapleVector<EACGBaseNode *> *> &GetCallSite2Nodes() const
202     {
203         return callSite2Nodes;
204     }
205 
206     void InitGlobalNode();
207     void AddMaps2Object(EACGObjectNode *caller, EACGObjectNode *callee);
208     void UpdateExprOfNode(EACGBaseNode &node, MeExpr *me);
209     void UpdateExprOfGlobalRef(MeExpr *me);
210     void PropogateEAStatus();
211     bool MergeCG(MapleVector<EACGBaseNode *> &caller, const MapleVector<EACGBaseNode *> *callee);
212     void TrimGlobalNode() const;
213     void UpdateEACGFromCaller(const MapleVector<EACGBaseNode *> &callerCallSiteArg,
214                               const MapleVector<EACGBaseNode *> &calleeFuncArg);
215     void DumpDotFile(const IRMap *irMap, bool dumpPt, MapleVector<EACGBaseNode *> *dumpVec = nullptr);
216     void DeleteEACG() const;
217     void RestoreStatus(bool old);
218     void CountObjEAStatus() const;
219 
GetFunctionName()220     const std::string &GetFunctionName() const
221     {
222         return GlobalTables::GetStrTable().GetStringFromStrIdx(funcStIdx);
223     }
224 
225 private:
226     MIRModule *mirModule;
227     MapleAllocator *alloc;
228     MapleVector<EACGBaseNode *> nodes;
229     MapleMap<MeExpr *, MapleSet<EACGBaseNode *> *> expr2Nodes;
230     // this vector contain func arg nodes first in declaration order and the last is return node
231     MapleVector<EACGBaseNode *> funcArgNodes;
232     MapleMap<uint32, MapleVector<EACGBaseNode *> *> callSite2Nodes;
233     GStrIdx funcStIdx;
234     bool hasUpdated;
235     bool needConv;
236     bool imported;
237     int exprIdMax;
238     EACGObjectNode *globalObj;
239     EACGRefNode *globalRef;
240     EACGFieldNode *globalField;
241     // this is used as a tmp varible for merge cg
242     std::map<EACGObjectNode *, std::set<EACGObjectNode *>> callee2Caller;
243     void CheckArgNodeOrder(MapleVector<EACGBaseNode *> &funcArgV);
244     void UpdateCallerNodes(const MapleVector<EACGBaseNode *> &caller, const MapleVector<EACGBaseNode *> &callee);
245     void UpdateCallerRetNode(MapleVector<EACGBaseNode *> &caller, const MapleVector<EACGBaseNode *> &callee);
246     void UpdateCallerEdges();
247     void UpdateCallerEdgesInternal(EACGObjectNode *node1, int32 fieldID, EACGObjectNode *node2);
248     void UpdateNodes(const EACGBaseNode &actualInCallee, EACGBaseNode &actualInCaller, bool firstTime);
249     void UpdateCallerWithCallee(EACGObjectNode &objInCaller, const EACGObjectNode &objInCallee, bool firstTime);
250 
SetCGUpdateFlag()251     void SetCGUpdateFlag()
252     {
253         hasUpdated = true;
254     }
255 };
256 
257 class EACGBaseNode {
258 public:
259     friend class BinaryMplExport;
260     friend class BinaryMplImport;
261     friend class EACGObjectNode;
262     friend class EACGFieldNode;
263     friend class EACGActualNode;
264     friend class EACGRefNode;
265     friend class EACGPointerNode;
266     friend class EAConnectionGraph;
267 
EACGBaseNode(MIRModule * m,MapleAllocator * a,NodeKind nk,EAConnectionGraph * ec)268     EACGBaseNode(MIRModule *m, MapleAllocator *a, NodeKind nk, EAConnectionGraph *ec)
269         : locInfo(nullptr), mirModule(m), alloc(a), kind(nk), meExpr(nullptr), eaStatus(kNoEscape), id(0), eaCG(ec)
270     {
271     }
272 
EACGBaseNode(MIRModule * m,MapleAllocator * a,NodeKind nk,EAConnectionGraph & ec,MeExpr * expr,EAStatus initialEas,int i)273     EACGBaseNode(MIRModule *m, MapleAllocator *a, NodeKind nk, EAConnectionGraph &ec, MeExpr *expr, EAStatus initialEas,
274                  int i)
275         : locInfo(nullptr), mirModule(m), alloc(a), kind(nk), meExpr(expr), eaStatus(initialEas), id(i), eaCG(&ec)
276     {
277         ec.SetCGUpdateFlag();
278     }
279 
280     virtual ~EACGBaseNode() = default;
281 
IsFieldNode()282     virtual bool IsFieldNode() const
283     {
284         return kind == kFieldNode;
285     }
286 
IsObjectNode()287     virtual bool IsObjectNode() const
288     {
289         return kind == kObejectNode;
290     }
291 
IsReferenceNode()292     virtual bool IsReferenceNode() const
293     {
294         return kind == kReferenceNode;
295     }
296 
IsActualNode()297     virtual bool IsActualNode() const
298     {
299         return kind == kActualNode;
300     }
301 
IsPointerNode()302     virtual bool IsPointerNode() const
303     {
304         return kind == kPointerNode;
305     }
306 
GetMeExpr()307     virtual const MeExpr *GetMeExpr() const
308     {
309         return meExpr;
310     }
311 
SetMeExpr(MeExpr & newExpr)312     virtual void SetMeExpr(MeExpr &newExpr)
313     {
314         if (IsFieldNode() && newExpr.GetMeOp() != kMeOpIvar && newExpr.GetMeOp() != kMeOpOp) {
315             CHECK_FATAL(false, "must be kMeOpIvar or kMeOpOp");
316         } else if (IsReferenceNode() == true && newExpr.GetMeOp() != kMeOpVar && newExpr.GetMeOp() != kMeOpReg &&
317                    newExpr.GetMeOp() != kMeOpAddrof && newExpr.GetMeOp() != kMeOpConststr) {
318             CHECK_FATAL(false, "must be kMeOpVar, kMeOpReg, kMeOpAddrof or kMeOpConststr");
319         }
320         meExpr = &newExpr;
321     }
322 
GetPointsToSet()323     const std::set<EACGObjectNode *> &GetPointsToSet() const
324     {
325         CHECK_FATAL(!IsPointerNode(), "must be pointer node");
326         return pointsTo;
327     };
328 
329     virtual bool AddOutNode(EACGBaseNode &newOut);
330 
GetEAStatus()331     virtual EAStatus GetEAStatus() const
332     {
333         return eaStatus;
334     }
335 
GetInSet()336     virtual const std::set<EACGBaseNode *> &GetInSet() const
337     {
338         return in;
339     }
340 
InsertInSet(EACGBaseNode * val)341     virtual void InsertInSet(EACGBaseNode *val)
342     {
343         (void)in.insert(val);
344     }
345 
GetOutSet()346     virtual const std::set<EACGBaseNode *> &GetOutSet() const
347     {
348         CHECK_FATAL(IsActualNode(), "must be actual node");
349         return out;
350     }
351 
InsertOutSet(EACGBaseNode * val)352     virtual void InsertOutSet(EACGBaseNode *val)
353     {
354         (void)out.insert(val);
355     }
356 
UpdateEAStatus(EAStatus newEas)357     virtual bool UpdateEAStatus(EAStatus newEas)
358     {
359         if (newEas > eaStatus) {
360             eaStatus = newEas;
361             PropagateEAStatusForNode(this);
362             eaCG->SetCGUpdateFlag();
363             return true;
364         }
365         return false;
366     }
367 
IsBelongTo(const EAConnectionGraph * cg)368     bool IsBelongTo(const EAConnectionGraph *cg) const
369     {
370         return this->eaCG == cg;
371     }
372 
GetEACG()373     const EAConnectionGraph *GetEACG() const
374     {
375         return eaCG;
376     }
377 
GetEACG()378     EAConnectionGraph *GetEACG()
379     {
380         return eaCG;
381     }
382 
SetEACG(EAConnectionGraph * cg)383     void SetEACG(EAConnectionGraph *cg)
384     {
385         this->eaCG = cg;
386     }
387 
SetID(int setId)388     void SetID(int setId)
389     {
390         this->id = static_cast<size_t>(setId);
391     }
392 
393     bool CanIgnoreRC() const;
394 
395 protected:
396     Location *locInfo;
397     MIRModule *mirModule;
398     MapleAllocator *alloc;
399     NodeKind kind;
400     MeExpr *meExpr;
401     EAStatus eaStatus;
402     size_t id;
403     // OBJ<->Field will not in following Set
404     std::set<EACGBaseNode *> in;
405     std::set<EACGBaseNode *> out;
406     std::set<EACGObjectNode *> pointsTo;
407     EAConnectionGraph *eaCG;
408 
409     virtual void CheckAllConnectionInNodes();
410     virtual std::string GetName(const IRMap *irMap) const;
411     virtual void DumpDotFile(std::ostream &, std::map<EACGBaseNode *, bool> &, bool, const IRMap *irMap = nullptr) = 0;
412     virtual void PropagateEAStatusForNode(const EACGBaseNode *subRoot) const;
413     virtual void GetNodeFormatInDot(std::string &label, std::string &color) const;
414     virtual bool UpdatePointsTo(const std::set<EACGObjectNode *> &cPointsTo);
415 
SetEAStatus(EAStatus status)416     virtual void SetEAStatus(EAStatus status)
417     {
418         this->eaStatus = status;
419     }
420 
GetNodeKind()421     virtual NodeKind GetNodeKind() const
422     {
423         return kind;
424     }
425 
426 private:
ReplaceByGlobalNode()427     virtual bool ReplaceByGlobalNode()
428     {
429         CHECK_FATAL(false, "impossible");
430         return false;
431     }
432 };
433 
434 class EACGPointerNode : public EACGBaseNode {
435 public:
436     friend class BinaryMplExport;
437     friend class BinaryMplImport;
EACGPointerNode(MIRModule * md,MapleAllocator * alloc,EAConnectionGraph * ec)438     EACGPointerNode(MIRModule *md, MapleAllocator *alloc, EAConnectionGraph *ec)
439         : EACGBaseNode(md, alloc, kPointerNode, ec), indirectLevel(0)
440     {
441     }
442 
EACGPointerNode(MIRModule * md,MapleAllocator * alloc,EAConnectionGraph & ec,MeExpr * expr,EAStatus initialEas,int i,int indirectL)443     EACGPointerNode(MIRModule *md, MapleAllocator *alloc, EAConnectionGraph &ec, MeExpr *expr, EAStatus initialEas,
444                     int i, int indirectL)
445         : EACGBaseNode(md, alloc, kPointerNode, ec, expr, initialEas, i), indirectLevel(indirectL) {};
446     ~EACGPointerNode() = default;
447 
SetLocation(Location * loc)448     void SetLocation(Location *loc)
449     {
450         this->locInfo = loc;
451     }
452 
GetIndirectLevel()453     int GetIndirectLevel() const
454     {
455         return indirectLevel;
456     }
457 
AddOutNode(EACGBaseNode & newOut)458     bool AddOutNode(EACGBaseNode &newOut) override
459     {
460         if (indirectLevel == 1) {
461             CHECK_FATAL(!newOut.IsPointerNode(), "must be pointer node");
462             (void)pointingTo.insert(&newOut);
463             (void)out.insert(&newOut);
464             (void)newOut.in.insert(this);
465         } else {
466             pointingTo.insert(&newOut);
467             CHECK_FATAL(pointingTo.size() == 1, "the size must be one");
468             CHECK_FATAL(newOut.IsPointerNode(), "must be pointer node");
469             CHECK_FATAL((indirectLevel - static_cast<EACGPointerNode &>(newOut).GetIndirectLevel()) == 1,
470                         "must be one");
471             (void)out.insert(&newOut);
472             (void)newOut.in.insert(this);
473         }
474         return false;
475     }
476 
GetPointingTo()477     const std::set<EACGBaseNode *> &GetPointingTo() const
478     {
479         return pointingTo;
480     }
481 
UpdatePointsTo(const std::set<EACGObjectNode * > &)482     bool UpdatePointsTo(const std::set<EACGObjectNode *> &) override
483     {
484         CHECK_FATAL(false, "impossible to update PointsTo");
485         return true;
486     };
487 
PropagateEAStatusForNode(const EACGBaseNode *)488     void PropagateEAStatusForNode(const EACGBaseNode *) const override
489     {
490         CHECK_FATAL(false, "impossible to propagate EA status for node");
491     }
492 
493     void DumpDotFile(std::ostream &fout, std::map<EACGBaseNode *, bool> &dumped, bool dumpPt,
494                      const IRMap *irMap = nullptr) override;
CheckAllConnectionInNodes()495     void CheckAllConnectionInNodes() override {}
496 
497 private:
498     int indirectLevel;
499     std::set<EACGBaseNode *> pointingTo;
ReplaceByGlobalNode()500     bool ReplaceByGlobalNode() override
501     {
502         CHECK_FATAL(false, "impossible to replace by global node");
503         return true;
504     }
505 };
506 
507 class EACGObjectNode : public EACGBaseNode {
508 public:
509     friend class EACGFieldNode;
510     friend class BinaryMplExport;
511     friend class BinaryMplImport;
EACGObjectNode(MIRModule * md,MapleAllocator * alloc,EAConnectionGraph * ec)512     EACGObjectNode(MIRModule *md, MapleAllocator *alloc, EAConnectionGraph *ec)
513         : EACGBaseNode(md, alloc, kObejectNode, ec), rcOperations(0), ignorRC(false), isPhantom(false)
514     {
515     }
516 
EACGObjectNode(MIRModule * md,MapleAllocator * alloc,EAConnectionGraph & ec,MeExpr * expr,EAStatus initialEas,int i,bool isPh)517     EACGObjectNode(MIRModule *md, MapleAllocator *alloc, EAConnectionGraph &ec, MeExpr *expr, EAStatus initialEas,
518                    int i, bool isPh)
519         : EACGBaseNode(md, alloc, kObejectNode, ec, expr, initialEas, i),
520           rcOperations(0),
521           ignorRC(false),
522           isPhantom(isPh)
523     {
524         (void)pointsBy.insert(this);
525         (void)pointsTo.insert(this);
526     };
527     ~EACGObjectNode() = default;
IsPhantom()528     bool IsPhantom() const
529     {
530         return isPhantom == true;
531     };
532 
SetLocation(Location * loc)533     void SetLocation(Location *loc)
534     {
535         this->locInfo = loc;
536     }
537 
GetFieldNodeMap()538     const std::map<FieldID, EACGFieldNode *> &GetFieldNodeMap() const
539     {
540         return fieldNodes;
541     }
542 
GetFieldNodeFromIdx(FieldID fId)543     EACGFieldNode *GetFieldNodeFromIdx(FieldID fId)
544     {
545         if (fieldNodes.find(-1) != fieldNodes.end()) {  // -1 expresses global
546             return fieldNodes[-1];
547         }
548         if (fieldNodes.find(fId) == fieldNodes.end()) {
549             return nullptr;
550         }
551         return fieldNodes[fId];
552     }
553 
554     bool AddOutNode(EACGBaseNode &newOut) override;
UpdatePointsTo(const std::set<EACGObjectNode * > &)555     bool UpdatePointsTo(const std::set<EACGObjectNode *> &) override
556     {
557         CHECK_FATAL(false, "impossible");
558         return true;
559     };
560 
561     bool IsPointedByFieldNode() const;
562     void PropagateEAStatusForNode(const EACGBaseNode *subRoot) const override;
563     void DumpDotFile(std::ostream &fout, std::map<EACGBaseNode *, bool> &dumped, bool dumpPt,
564                      const IRMap *irMap = nullptr) override;
565     void CheckAllConnectionInNodes() override;
566 
Insert2PointsBy(EACGBaseNode * node)567     void Insert2PointsBy(EACGBaseNode *node)
568     {
569         (void)pointsBy.insert(node);
570     }
571 
EraseNodeFromPointsBy(EACGBaseNode * node)572     void EraseNodeFromPointsBy(EACGBaseNode *node)
573     {
574         pointsBy.erase(node);
575     }
576 
IncresRCOperations()577     void IncresRCOperations()
578     {
579         ++rcOperations;
580     }
581 
IncresRCOperations(int num)582     void IncresRCOperations(int num)
583     {
584         rcOperations += num;
585     }
586 
GetRCOperations()587     int GetRCOperations() const
588     {
589         return rcOperations;
590     }
591 
GetIgnorRC()592     bool GetIgnorRC() const
593     {
594         return ignorRC;
595     }
596 
SetIgnorRC(bool ignore)597     void SetIgnorRC(bool ignore)
598     {
599         ignorRC = ignore;
600     }
601 
602 private:
603     std::set<EACGBaseNode *> pointsBy;
604     int rcOperations;
605     bool ignorRC;
606     bool isPhantom;
607     std::map<FieldID, EACGFieldNode *> fieldNodes;
608     bool ReplaceByGlobalNode() override;
609 };
610 
611 class EACGRefNode : public EACGBaseNode {
612 public:
613     friend class BinaryMplExport;
614     friend class BinaryMplImport;
EACGRefNode(MIRModule * md,MapleAllocator * alloc,EAConnectionGraph * ec)615     EACGRefNode(MIRModule *md, MapleAllocator *alloc, EAConnectionGraph *ec)
616         : EACGBaseNode(md, alloc, kReferenceNode, ec), isStaticField(false), sym(nullptr), version(0)
617     {
618     }
619 
620     EACGRefNode(MIRModule *md, MapleAllocator *alloc, EAConnectionGraph &ec, MeExpr *expr, EAStatus initialEas, int i,
621                 bool isS = false)
EACGBaseNode(md,alloc,kReferenceNode,ec,expr,initialEas,i)622         : EACGBaseNode(md, alloc, kReferenceNode, ec, expr, initialEas, i),
623           isStaticField(isS),
624           sym(nullptr),
625           version(0) {};
626     ~EACGRefNode() = default;
IsStaticRef()627     bool IsStaticRef() const
628     {
629         return isStaticField;
630     };
SetSymbolAndVersion(MIRSymbol * mirSym,int versionIdx)631     void SetSymbolAndVersion(MIRSymbol *mirSym, int versionIdx)
632     {
633         if (sym != nullptr) {
634             CHECK_FATAL(sym == mirSym, "must be sym");
635             CHECK_FATAL(versionIdx == version, "must be version ");
636         }
637         sym = mirSym;
638         version = versionIdx;
639     };
640 
641     void DumpDotFile(std::ostream &fout, std::map<EACGBaseNode *, bool> &dumped, bool dumpPt,
642                      const IRMap *irMap = nullptr);
643 
644 private:
645     bool isStaticField;
646     MIRSymbol *sym;
647     int version;
648     bool ReplaceByGlobalNode();
649 };
650 class EACGFieldNode : public EACGBaseNode {
651 public:
652     friend class BinaryMplExport;
653     friend class BinaryMplImport;
654     friend class EACGObjectNode;
EACGFieldNode(MIRModule * md,MapleAllocator * alloc,EAConnectionGraph * ec)655     EACGFieldNode(MIRModule *md, MapleAllocator *alloc, EAConnectionGraph *ec)
656         : EACGBaseNode(md, alloc, kFieldNode, ec), fieldID(0), isPhantom(false), sym(nullptr), version(0), mirFieldId(0)
657     {
658     }
659 
EACGFieldNode(MIRModule * md,MapleAllocator * alloc,EAConnectionGraph & ec,MeExpr * expr,EAStatus initialEas,int i,FieldID fId,EACGObjectNode * bt,bool isPh)660     EACGFieldNode(MIRModule *md, MapleAllocator *alloc, EAConnectionGraph &ec, MeExpr *expr, EAStatus initialEas, int i,
661                   FieldID fId, EACGObjectNode *bt, bool isPh)
662         : EACGBaseNode(md, alloc, kFieldNode, ec, expr, initialEas, i),
663           fieldID(fId),
664           isPhantom(isPh),
665           sym(nullptr),
666           version(0),
667           mirFieldId(0)
668     {
669         bt->fieldNodes[fieldID] = this;
670         (void)belongsTo.insert(bt);
671     };
672 
673     ~EACGFieldNode() = default;
674 
GetFieldID()675     FieldID GetFieldID() const
676     {
677         return fieldID;
678     };
679 
SetFieldID(FieldID id)680     void SetFieldID(FieldID id)
681     {
682         fieldID = id;
683     }
684 
IsPhantom()685     bool IsPhantom() const
686     {
687         return isPhantom;
688     }
689 
GetBelongsToObj()690     const std::set<EACGObjectNode *> &GetBelongsToObj() const
691     {
692         return belongsTo;
693     }
694 
AddBelongTo(EACGObjectNode * newObj)695     void AddBelongTo(EACGObjectNode *newObj)
696     {
697         (void)belongsTo.insert(newObj);
698     }
699 
SetSymbolAndVersion(MIRSymbol * mirSym,int versionIdx,FieldID fID)700     void SetSymbolAndVersion(MIRSymbol *mirSym, int versionIdx, FieldID fID)
701     {
702         if (sym != nullptr) {
703             CHECK_FATAL(sym == mirSym, "must be mirSym");
704             CHECK_FATAL(version == versionIdx, "must be version");
705             CHECK_FATAL(mirFieldId == fID, "must be  mir FieldId");
706         }
707         sym = mirSym;
708         version = versionIdx;
709         mirFieldId = fID;
710     };
711 
712     void DumpDotFile(std::ostream &fout, std::map<EACGBaseNode *, bool> &dumped, bool dumpPt,
713                      const IRMap *irMap = nullptr);
714 
715 private:
716     FieldID fieldID;
717     std::set<EACGObjectNode *> belongsTo;
718     bool isPhantom;
719     MIRSymbol *sym;
720     int version;
721     FieldID mirFieldId;
722     bool ReplaceByGlobalNode();
723 };
724 
725 class EACGActualNode : public EACGBaseNode {
726 public:
727     friend class BinaryMplExport;
728     friend class BinaryMplImport;
EACGActualNode(MIRModule * md,MapleAllocator * alloc,EAConnectionGraph * ec)729     EACGActualNode(MIRModule *md, MapleAllocator *alloc, EAConnectionGraph *ec)
730         : EACGBaseNode(md, alloc, kActualNode, ec), isReturn(false), isPhantom(false), argIdx(0), callSiteInfo(0) {};
EACGActualNode(MIRModule * md,MapleAllocator * alloc,EAConnectionGraph & ec,MeExpr * expr,EAStatus initialEas,int i,bool isR,bool isPh,uint8 aI,uint32 callSite)731     EACGActualNode(MIRModule *md, MapleAllocator *alloc, EAConnectionGraph &ec, MeExpr *expr, EAStatus initialEas,
732                    int i, bool isR, bool isPh, uint8 aI, uint32 callSite)
733         : EACGBaseNode(md, alloc, kActualNode, ec, expr, initialEas, i),
734           isReturn(isR),
735           isPhantom(isPh),
736           argIdx(aI),
737           callSiteInfo(callSite) {};
738     ~EACGActualNode() = default;
739 
IsReturn()740     bool IsReturn() const
741     {
742         return isReturn;
743     };
744 
IsPhantom()745     bool IsPhantom() const
746     {
747         return isPhantom;
748     };
749 
GetArgIndex()750     uint32 GetArgIndex() const
751     {
752         return argIdx;
753     };
754 
GetCallSite()755     uint32 GetCallSite() const
756     {
757         return callSiteInfo;
758     }
759 
760     void DumpDotFile(std::ostream &fout, std::map<EACGBaseNode *, bool> &dumped, bool dumpPt,
761                      const IRMap *irMap = nullptr);
762 
763 private:
764     bool isReturn;
765     bool isPhantom;
766     uint8 argIdx;
767     uint32 callSiteInfo;
768     bool ReplaceByGlobalNode();
769 };
770 }  // namespace maple
771 #endif
772