• 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 /*
17  * The file defines the data structures of Control Dependence Graph(CDG).
18  */
19 #ifndef MAPLEBE_INCLUDE_CG_CG_CDG_H
20 #define MAPLEBE_INCLUDE_CG_CG_CDG_H
21 
22 #include <string>
23 #include "cgfunc.h"
24 #include "mpl_number.h"
25 #include "deps.h"
26 #include "mempool_allocator.h"
27 
28 namespace maplebe {
29 class CDGNode;
30 class CDGEdge;
31 class CDGRegion;
32 using CDGNodeId = utils::Index<CDGNode>;
33 using CDGRegionId = utils::Index<CDGRegion>;
34 
35 // Encapsulation of BB
36 class CDGNode {
37 public:
CDGNode(CDGNodeId nId,BB & bb,MapleAllocator & alloc)38     CDGNode(CDGNodeId nId, BB &bb, MapleAllocator &alloc)
39         : id(nId),
40           bb(&bb),
41           outEdges(alloc.Adapter()),
42           inEdges(alloc.Adapter()),
43           lastComments(alloc.Adapter()),
44           dataNodes(alloc.Adapter()),
45           cfiInsns(alloc.Adapter())
46     {
47     }
~CDGNode()48     virtual ~CDGNode()
49     {
50         topoPredInRegion = nullptr;
51         lastFrameDef = nullptr;
52         bb = nullptr;
53         regUses = nullptr;
54         mayThrows = nullptr;
55         ehInRegs = nullptr;
56         heapDefs = nullptr;
57         ambiInsns = nullptr;
58         membarInsn = nullptr;
59         pseudoSepNodes = nullptr;
60         lastCallInsn = nullptr;
61         lastInlineAsmInsn = nullptr;
62         regDefs = nullptr;
63         stackDefs = nullptr;
64         region = nullptr;
65         heapUses = nullptr;
66         stackUses = nullptr;
67     }
68 
GetBB()69     BB *GetBB()
70     {
71         return bb;
72     }
73 
GetBB()74     const BB *GetBB() const
75     {
76         return bb;
77     }
78 
GetNodeId()79     CDGNodeId GetNodeId()
80     {
81         return id;
82     }
83 
GetNodeId()84     CDGNodeId GetNodeId() const
85     {
86         return id;
87     }
88 
SetNodeId(CDGNodeId nId)89     void SetNodeId(CDGNodeId nId)
90     {
91         id = nId;
92     }
93 
GetRegion()94     CDGRegion *GetRegion()
95     {
96         return region;
97     }
98 
GetRegion()99     const CDGRegion *GetRegion() const
100     {
101         return region;
102     }
103 
SetRegion(CDGRegion * cdgRegion)104     void SetRegion(CDGRegion *cdgRegion)
105     {
106         region = cdgRegion;
107     }
108 
ClearRegion()109     void ClearRegion()
110     {
111         region = nullptr;
112     }
113 
IsEntryNode()114     bool IsEntryNode() const
115     {
116         return isEntryNode;
117     }
118 
SetEntryNode()119     void SetEntryNode()
120     {
121         isEntryNode = true;
122     }
123 
IsExitNode()124     bool IsExitNode() const
125     {
126         return isExitNode;
127     }
128 
SetExitNode()129     void SetExitNode()
130     {
131         isExitNode = true;
132     }
133 
AddOutEdges(CDGEdge * edge)134     void AddOutEdges(CDGEdge *edge)
135     {
136         outEdges.emplace_back(edge);
137     }
138 
GetAllOutEdges()139     MapleVector<CDGEdge *> &GetAllOutEdges()
140     {
141         return outEdges;
142     }
143 
AddInEdges(CDGEdge * edge)144     void AddInEdges(CDGEdge *edge)
145     {
146         inEdges.emplace_back(edge);
147     }
148 
GetAllInEdges()149     MapleVector<CDGEdge *> &GetAllInEdges()
150     {
151         return inEdges;
152     }
153 
GetOutEdgesNum()154     std::size_t GetOutEdgesNum() const
155     {
156         return outEdges.size();
157     }
158 
GetInEdgesNum()159     std::size_t GetInEdgesNum() const
160     {
161         return inEdges.size();
162     }
163 
SetVisitedInTopoSort(bool isVisited)164     void SetVisitedInTopoSort(bool isVisited)
165     {
166         isVisitedInTopoSort = isVisited;
167     }
168 
IsVisitedInTopoSort()169     bool IsVisitedInTopoSort() const
170     {
171         return isVisitedInTopoSort;
172     }
173 
SetVisitedInExtendedFind()174     void SetVisitedInExtendedFind()
175     {
176         isVisitedInExtendedFind = true;
177     }
178 
IsVisitedInExtendedFind()179     bool IsVisitedInExtendedFind() const
180     {
181         return isVisitedInExtendedFind;
182     }
183 
GetInsnNum()184     uint32 GetInsnNum() const
185     {
186         return insnNum;
187     }
188 
SetInsnNum(uint32 num)189     void SetInsnNum(uint32 num)
190     {
191         insnNum = num;
192     }
193 
HasAmbiRegs()194     bool HasAmbiRegs() const
195     {
196         return hasAmbiRegs;
197     }
198 
SetHasAmbiRegs(bool flag)199     void SetHasAmbiRegs(bool flag)
200     {
201         hasAmbiRegs = flag;
202     }
203 
GetMembarInsn()204     Insn *GetMembarInsn()
205     {
206         return membarInsn;
207     }
208 
SetMembarInsn(Insn * insn)209     void SetMembarInsn(Insn *insn)
210     {
211         membarInsn = insn;
212     }
213 
GetLastCallInsn()214     Insn *GetLastCallInsn()
215     {
216         return lastCallInsn;
217     }
218 
SetLastCallInsn(Insn * callInsn)219     void SetLastCallInsn(Insn *callInsn)
220     {
221         lastCallInsn = callInsn;
222     }
223 
GetLastFrameDefInsn()224     Insn *GetLastFrameDefInsn()
225     {
226         return lastFrameDef;
227     }
228 
SetLastFrameDefInsn(Insn * frameInsn)229     void SetLastFrameDefInsn(Insn *frameInsn)
230     {
231         lastFrameDef = frameInsn;
232     }
233 
GetLastInlineAsmInsn()234     Insn *GetLastInlineAsmInsn()
235     {
236         return lastInlineAsmInsn;
237     }
238 
SetLastInlineAsmInsn(Insn * asmInsn)239     void SetLastInlineAsmInsn(Insn *asmInsn)
240     {
241         lastInlineAsmInsn = asmInsn;
242     }
243 
InitTopoInRegionInfo(MemPool & tmpMp,MapleAllocator & tmpAlloc)244     void InitTopoInRegionInfo(MemPool &tmpMp, MapleAllocator &tmpAlloc)
245     {
246         topoPredInRegion = tmpMp.New<MapleSet<CDGNodeId>>(tmpAlloc.Adapter());
247     }
248 
ClearTopoInRegionInfo()249     void ClearTopoInRegionInfo()
250     {
251         topoPredInRegion = nullptr;
252     }
253 
InitDataDepInfo(MemPool & tmpMp,MapleAllocator & tmpAlloc,uint32 maxRegNum)254     void InitDataDepInfo(MemPool &tmpMp, MapleAllocator &tmpAlloc, uint32 maxRegNum)
255     {
256         regDefs = tmpMp.New<MapleVector<Insn *>>(tmpAlloc.Adapter());
257         regUses = tmpMp.New<MapleVector<RegList *>>(tmpAlloc.Adapter());
258         stackUses = tmpMp.New<MapleVector<Insn *>>(tmpAlloc.Adapter());
259         stackDefs = tmpMp.New<MapleVector<Insn *>>(tmpAlloc.Adapter());
260         heapUses = tmpMp.New<MapleVector<Insn *>>(tmpAlloc.Adapter());
261         heapDefs = tmpMp.New<MapleVector<Insn *>>(tmpAlloc.Adapter());
262         mayThrows = tmpMp.New<MapleVector<Insn *>>(tmpAlloc.Adapter());
263         ambiInsns = tmpMp.New<MapleVector<Insn *>>(tmpAlloc.Adapter());
264         pseudoSepNodes = tmpMp.New<MapleVector<DepNode *>>(tmpAlloc.Adapter());
265         ehInRegs = tmpMp.New<MapleSet<regno_t>>(tmpAlloc.Adapter());
266 
267         regDefs->resize(maxRegNum);
268         regUses->resize(maxRegNum);
269     }
270 
ClearDataDepInfo()271     void ClearDataDepInfo()
272     {
273         membarInsn = nullptr;
274         lastCallInsn = nullptr;
275         lastFrameDef = nullptr;
276         lastInlineAsmInsn = nullptr;
277         lastComments.clear();
278 
279         regDefs = nullptr;
280         regUses = nullptr;
281         stackUses = nullptr;
282         stackDefs = nullptr;
283         heapUses = nullptr;
284         heapDefs = nullptr;
285         mayThrows = nullptr;
286         ambiInsns = nullptr;
287         pseudoSepNodes = nullptr;
288         ehInRegs = nullptr;
289     }
290 
ClearDepDataVec()291     void ClearDepDataVec()
292     {
293         membarInsn = nullptr;
294         lastCallInsn = nullptr;
295         lastFrameDef = nullptr;
296         lastInlineAsmInsn = nullptr;
297 
298         for (auto &regDef : *regDefs) {
299             regDef = nullptr;
300         }
301         for (auto &regUse : *regUses) {
302             regUse = nullptr;
303         }
304 
305         stackUses->clear();
306         stackDefs->clear();
307         heapUses->clear();
308         heapDefs->clear();
309         mayThrows->clear();
310         ambiInsns->clear();
311     }
312 
GetLatestDefInsn(regno_t regNO)313     Insn *GetLatestDefInsn(regno_t regNO)
314     {
315         return (*regDefs)[regNO];
316     }
317 
SetLatestDefInsn(regno_t regNO,Insn * defInsn)318     void SetLatestDefInsn(regno_t regNO, Insn *defInsn)
319     {
320         (*regDefs)[regNO] = defInsn;
321     }
322 
GetUseInsnChain(regno_t regNO)323     RegList *GetUseInsnChain(regno_t regNO)
324     {
325         return (*regUses)[regNO];
326     }
327 
AppendUseInsnChain(regno_t regNO,Insn * useInsn,MemPool & mp)328     void AppendUseInsnChain(regno_t regNO, Insn *useInsn, MemPool &mp)
329     {
330         CHECK_FATAL(useInsn != nullptr, "invalid useInsn");
331         auto *newUse = mp.New<RegList>();
332         newUse->insn = useInsn;
333         newUse->next = nullptr;
334 
335         RegList *headUse = (*regUses)[regNO];
336         if (headUse == nullptr) {
337             (*regUses)[regNO] = newUse;
338         } else {
339             while (headUse->next != nullptr) {
340                 headUse = headUse->next;
341             }
342             headUse->next = newUse;
343         }
344     }
345 
ClearUseInsnChain(regno_t regNO)346     void ClearUseInsnChain(regno_t regNO)
347     {
348         (*regUses)[regNO] = nullptr;
349     }
350 
GetStackUseInsns()351     MapleVector<Insn *> &GetStackUseInsns()
352     {
353         return *stackUses;
354     }
355 
AddStackUseInsn(Insn * stackInsn)356     void AddStackUseInsn(Insn *stackInsn)
357     {
358         stackUses->emplace_back(stackInsn);
359     }
360 
GetStackDefInsns()361     MapleVector<Insn *> &GetStackDefInsns()
362     {
363         return *stackDefs;
364     }
365 
AddStackDefInsn(Insn * stackInsn)366     void AddStackDefInsn(Insn *stackInsn)
367     {
368         stackDefs->emplace_back(stackInsn);
369     }
370 
GetHeapUseInsns()371     MapleVector<Insn *> &GetHeapUseInsns()
372     {
373         return *heapUses;
374     }
375 
AddHeapUseInsn(Insn * heapInsn)376     void AddHeapUseInsn(Insn *heapInsn) const
377     {
378         heapUses->emplace_back(heapInsn);
379     }
380 
GetHeapDefInsns()381     MapleVector<Insn *> &GetHeapDefInsns()
382     {
383         return *heapDefs;
384     }
385 
AddHeapDefInsn(Insn * heapInsn)386     void AddHeapDefInsn(Insn *heapInsn) const
387     {
388         heapDefs->emplace_back(heapInsn);
389     }
390 
GetMayThrowInsns()391     MapleVector<Insn *> &GetMayThrowInsns()
392     {
393         return *mayThrows;
394     }
395 
AddMayThrowInsn(Insn * throwInsn)396     void AddMayThrowInsn(Insn *throwInsn)
397     {
398         mayThrows->emplace_back(throwInsn);
399     }
400 
GetAmbiguousInsns()401     MapleVector<Insn *> &GetAmbiguousInsns()
402     {
403         return *ambiInsns;
404     }
405 
AddAmbiguousInsn(Insn * ambiInsn)406     void AddAmbiguousInsn(Insn *ambiInsn) const
407     {
408         ambiInsns->emplace_back(ambiInsn);
409     }
410 
GetTopoPredInRegion()411     MapleSet<CDGNodeId> &GetTopoPredInRegion()
412     {
413         return *topoPredInRegion;
414     }
415 
InsertVisitedTopoPredInRegion(CDGNodeId nodeId)416     void InsertVisitedTopoPredInRegion(CDGNodeId nodeId) const
417     {
418         topoPredInRegion->insert(nodeId);
419     }
420 
GetLastComments()421     MapleVector<Insn *> &GetLastComments()
422     {
423         return lastComments;
424     }
425 
AddCommentInsn(Insn * commentInsn)426     void AddCommentInsn(Insn *commentInsn)
427     {
428         lastComments.emplace_back(commentInsn);
429     }
430 
CopyAndClearComments(MapleVector<Insn * > & comments)431     void CopyAndClearComments(MapleVector<Insn *> &comments)
432     {
433         lastComments = comments;
434         comments.clear();
435     }
436 
ClearLastComments()437     void ClearLastComments()
438     {
439         lastComments.clear();
440     }
441 
AddPseudoSepNodes(DepNode * node)442     void AddPseudoSepNodes(DepNode *node) const
443     {
444         pseudoSepNodes->emplace_back(node);
445     }
446 
GetEhInRegs()447     MapleSet<regno_t> &GetEhInRegs()
448     {
449         return *ehInRegs;
450     }
451 
GetAllDataNodes()452     MapleVector<DepNode *> &GetAllDataNodes()
453     {
454         return dataNodes;
455     }
456 
AddDataNode(DepNode * depNode)457     void AddDataNode(DepNode *depNode)
458     {
459         (void)dataNodes.emplace_back(depNode);
460     }
461 
ClearDataNodes()462     void ClearDataNodes()
463     {
464         dataNodes.clear();
465     }
466 
GetCfiInsns()467     MapleVector<Insn *> &GetCfiInsns()
468     {
469         return cfiInsns;
470     }
471 
AddCfiInsn(Insn * cfiInsn)472     void AddCfiInsn(Insn *cfiInsn)
473     {
474         (void)cfiInsns.emplace_back(cfiInsn);
475     }
476 
RemoveDepNodeFromDataNodes(const DepNode & depNode)477     void RemoveDepNodeFromDataNodes(const DepNode &depNode)
478     {
479         for (auto iter = dataNodes.begin(); iter != dataNodes.end(); ++iter) {
480             if (*iter == &depNode) {
481                 void(dataNodes.erase(iter));
482                 break;
483             }
484         }
485     }
486 
InitPredNodeSumInRegion(int32 predSum)487     void InitPredNodeSumInRegion(int32 predSum)
488     {
489         CHECK_FATAL(predSum >= 0, "invalid predSum");
490         predNodesInRegion = predSum;
491     }
492 
DecPredNodeSumInRegion()493     void DecPredNodeSumInRegion()
494     {
495         predNodesInRegion--;
496     }
497 
IsAllPredInRegionProcessed()498     bool IsAllPredInRegionProcessed() const
499     {
500         return (predNodesInRegion == 0);
501     }
502 
GetNodeSum()503     uint32 &GetNodeSum()
504     {
505         return nodeSum;
506     }
507 
AccNodeSum()508     void AccNodeSum()
509     {
510         nodeSum++;
511     }
512 
SetNodeSum(uint32 sum)513     void SetNodeSum(uint32 sum)
514     {
515         nodeSum = sum;
516     }
517 
518     bool operator!=(const CDGNode &node)
519     {
520         if (this != &node) {
521             return true;
522         }
523         if (this->id != node.GetNodeId() || this->bb != node.GetBB() || this->region != node.GetRegion()) {
524             return true;
525         }
526         if (this->GetInEdgesNum() != node.GetInEdgesNum() || this->GetOutEdgesNum() != node.GetOutEdgesNum()) {
527             return true;
528         }
529         return false;
530     }
531 
532 private:
533     CDGNodeId id;  // same to bbId
534     BB *bb = nullptr;
535     CDGRegion *region = nullptr;
536     bool isEntryNode = false;
537     bool isExitNode = false;
538     MapleVector<CDGEdge *> outEdges;
539     MapleVector<CDGEdge *> inEdges;
540     bool isVisitedInTopoSort = false;      // for sorting nodes in region by topological order
541     bool isVisitedInExtendedFind = false;  // for finding a fallthrough path as a region
542     uint32 insnNum = 0;                    // record insn total num of BB
543     // The following structures are used to record data flow infos in building data dependence among insns
544     bool hasAmbiRegs = false;
545     Insn *membarInsn = nullptr;
546     Insn *lastCallInsn = nullptr;
547     Insn *lastFrameDef = nullptr;
548     Insn *lastInlineAsmInsn = nullptr;
549     MapleVector<Insn *> *regDefs = nullptr;     // the index is regNO, record the latest defInsn in the curBB
550     MapleVector<RegList *> *regUses = nullptr;  // the index is regNO
551     MapleVector<Insn *> *stackUses = nullptr;
552     MapleVector<Insn *> *stackDefs = nullptr;
553     MapleVector<Insn *> *heapUses = nullptr;
554     MapleVector<Insn *> *heapDefs = nullptr;
555     MapleVector<Insn *> *mayThrows = nullptr;
556     MapleVector<Insn *> *ambiInsns = nullptr;
557     MapleVector<DepNode *> *pseudoSepNodes = nullptr;
558     MapleSet<regno_t> *ehInRegs = nullptr;
559     MapleSet<CDGNodeId> *topoPredInRegion = nullptr;
560     MapleVector<Insn *> lastComments;
561     MapleVector<DepNode *> dataNodes;
562     MapleVector<Insn *> cfiInsns;
563     // For computing topological order of cdgNodes in a region,
564     // which is initialized to the number of pred nodes in CFG at the beginning of processing the region,
565     // and change dynamically
566     int32 predNodesInRegion = -1;
567     // For intra-block dda: it accumulates from the first insn (nodeSum = 1) of bb
568     // For inter-block dda: it accumulates from the maximum of nodeSum in all the predecessor of cur cdgNode
569     uint32 nodeSum = 0;
570 };
571 
572 class CDGEdge {
573 public:
CDGEdge(CDGNode & from,CDGNode & to,int32 cond)574     CDGEdge(CDGNode &from, CDGNode &to, int32 cond) : fromNode(from), toNode(to), condition(cond) {}
575     virtual ~CDGEdge() = default;
576 
GetFromNode()577     CDGNode &GetFromNode()
578     {
579         return fromNode;
580     }
581 
GetFromNode()582     CDGNode &GetFromNode() const
583     {
584         return fromNode;
585     }
586 
SetFromNode(const CDGNode & from)587     void SetFromNode(const CDGNode &from)
588     {
589         fromNode = from;
590     }
591 
GetToNode()592     CDGNode &GetToNode()
593     {
594         return toNode;
595     }
596 
GetToNode()597     CDGNode &GetToNode() const
598     {
599         return toNode;
600     }
601 
SetToNode(const CDGNode & to)602     void SetToNode(const CDGNode &to)
603     {
604         toNode = to;
605     }
606 
GetCondition()607     int32 GetCondition() const
608     {
609         return condition;
610     }
611 
SetCondition(int32 cond)612     void SetCondition(int32 cond)
613     {
614         condition = cond;
615     }
616 
617     // for checking same control dependence
618     bool operator==(const CDGEdge &edge)
619     {
620         if (this == &edge) {
621             return true;
622         }
623         if (this->fromNode != edge.GetFromNode()) {
624             return false;
625         }
626         if (this->toNode != edge.GetToNode()) {
627             return false;
628         }
629         if (this->condition != edge.GetCondition()) {
630             return false;
631         }
632         return true;
633     }
634 
635 private:
636     CDGNode &fromNode;
637     CDGNode &toNode;
638     // allocate different COND number to different succ edges of the same fromBB
639     // default value is -1 indicated no cond.
640     int32 condition;
641 };
642 
643 // A region consists of nodes with the same control dependence sets
644 class CDGRegion {
645 public:
CDGRegion(CDGRegionId rId,MapleAllocator & alloc)646     CDGRegion(CDGRegionId rId, MapleAllocator &alloc) : id(rId), memberNodes(alloc.Adapter()), cdEdges(alloc.Adapter())
647     {
648     }
~CDGRegion()649     virtual ~CDGRegion()
650     {
651         root = nullptr;
652     }
653 
GetRegionId()654     CDGRegionId GetRegionId()
655     {
656         return id;
657     }
658 
GetRegionNodes()659     MapleVector<CDGNode *> &GetRegionNodes()
660     {
661         return memberNodes;
662     }
663 
GetRegionNodeSize()664     std::size_t GetRegionNodeSize() const
665     {
666         return memberNodes.size();
667     }
668 
669     // Ensure the node is unique
AddCDGNode(CDGNode * node)670     void AddCDGNode(CDGNode *node)
671     {
672         if (std::find(memberNodes.cbegin(), memberNodes.cend(), node) == memberNodes.cend()) {
673             memberNodes.emplace_back(node);
674         }
675     }
676 
RemoveCDGNode(CDGNode * node)677     void RemoveCDGNode(CDGNode *node)
678     {
679         auto it = std::find(memberNodes.begin(), memberNodes.end(), node);
680         if (it == memberNodes.end()) {
681             return;
682         }
683         (void)memberNodes.erase(it);
684     }
685 
GetCDGNodeById(CDGNodeId nodeId)686     CDGNode *GetCDGNodeById(CDGNodeId nodeId)
687     {
688         for (auto cdgNode : memberNodes) {
689             if (cdgNode->GetNodeId() == nodeId) {
690                 return cdgNode;
691             }
692         }
693         return nullptr;
694     }
695 
GetCDEdges()696     MapleVector<CDGEdge *> &GetCDEdges()
697     {
698         return cdEdges;
699     }
700 
AddCDEdge(CDGEdge * edge)701     void AddCDEdge(CDGEdge *edge)
702     {
703         cdEdges.emplace_back(edge);
704     }
705 
AddCDEdgeSet(MapleVector<CDGEdge * > & cds)706     void AddCDEdgeSet(MapleVector<CDGEdge *> &cds)
707     {
708         for (auto &cd : cds) {
709             cdEdges.emplace_back(cd);
710         }
711     }
712 
GetMaxBBIdInRegion()713     uint32 GetMaxBBIdInRegion()
714     {
715         uint32 maxId = 0;
716         for (auto node : memberNodes) {
717             maxId = (node->GetNodeId() > maxId ? static_cast<uint32>(node->GetNodeId()) : maxId);
718         }
719         return maxId;
720     }
721 
SetRegionRoot(CDGNode & node)722     void SetRegionRoot(CDGNode &node)
723     {
724         root = &node;
725     }
726 
GetRegionRoot()727     CDGNode *GetRegionRoot()
728     {
729         return root;
730     }
731 
SetBackBBId(BBID bbId)732     void SetBackBBId(BBID bbId)
733     {
734         backEdgeFromBBId = bbId;
735     }
736 
GetBackBBId()737     BBID GetBackBBId() const
738     {
739         return backEdgeFromBBId;
740     }
741 
742 private:
743     CDGRegionId id;
744     MapleVector<CDGNode *> memberNodes;  // The nodes in CDGRegion by topological order
745     // The control dependence sets of the parent node.
746     // If it is a general non-linear region, the cdEdges is empty.
747     MapleVector<CDGEdge *> cdEdges;
748     CDGNode *root = nullptr;
749     BBID backEdgeFromBBId = UINT32_MAX;  // For loop region
750 };
751 
752 // Forward Control Dependence Graph
753 // which does not compute the control dependence on the back edges
754 class FCDG {
755 public:
FCDG(const CGFunc & f,MapleAllocator & alloc)756     FCDG(const CGFunc &f, MapleAllocator &alloc)
757         : nodes(f.GetAllBBSize(), alloc.Adapter()),
758           fcds(alloc.Adapter()),
759           regions(f.GetAllBBSize() + 1, alloc.Adapter())
760     {
761     }
762     virtual ~FCDG() = default;
763 
GetAllFCDGNodes()764     MapleVector<CDGNode *> &GetAllFCDGNodes()
765     {
766         return nodes;
767     }
768 
GetFCDGNodeSize()769     std::size_t GetFCDGNodeSize() const
770     {
771         return nodes.size();
772     }
773 
GetCDGNodeFromId(CDGNodeId id)774     CDGNode *GetCDGNodeFromId(CDGNodeId id)
775     {
776         return nodes[id];
777     }
778 
GetAllFCDGEdges()779     MapleVector<CDGEdge *> &GetAllFCDGEdges()
780     {
781         return fcds;
782     }
783 
GetAllRegions()784     MapleVector<CDGRegion *> &GetAllRegions()
785     {
786         return regions;
787     }
788 
GetRegionFromId(CDGRegionId id)789     CDGRegion *GetRegionFromId(CDGRegionId id)
790     {
791         return regions[id];
792     }
793 
794     // Ensure the node is unique
AddFCDGNode(CDGNode & node)795     void AddFCDGNode(CDGNode &node)
796     {
797         if (nodes[node.GetNodeId()] == nullptr) {
798             nodes[node.GetNodeId()] = &node;
799         }
800     }
801 
AddFCDGEdge(CDGEdge * edge)802     void AddFCDGEdge(CDGEdge *edge)
803     {
804         fcds.emplace_back(edge);
805     }
806 
807     // Ensure the region is unique
AddRegion(CDGRegion & region)808     void AddRegion(CDGRegion &region)
809     {
810         if (regions[region.GetRegionId()] == nullptr) {
811             regions[region.GetRegionId()] = &region;
812         }
813     }
814 
RemoveRegionById(CDGRegionId id)815     void RemoveRegionById(CDGRegionId id)
816     {
817         regions[id] = nullptr;
818     }
819 
820     // Provide interfaces for global scheduling
821 
822 private:
823     MapleVector<CDGNode *> nodes;      // all CDGNodes in FCDG that use nodeId as the index
824     MapleVector<CDGEdge *> fcds;       // all forward-control-dependence in FCDG
825     MapleVector<CDGRegion *> regions;  // all regions in FCDG that use CDGRegionId as the index
826 };
827 
828 struct CDGOutEdgeComparator {
operatorCDGOutEdgeComparator829     bool operator()(const CDGEdge &outEdge1, const CDGEdge &outEdge2) const
830     {
831         const CDGNode &toNode1 = outEdge1.GetToNode();
832         const CDGNode &toNode2 = outEdge2.GetToNode();
833         return toNode1.GetNodeId() < toNode2.GetNodeId();
834     }
835 };
836 
837 struct CDGInEdgeComparator {
operatorCDGInEdgeComparator838     bool operator()(const CDGEdge &inEdge1, const CDGEdge &inEdge2) const
839     {
840         const CDGNode &fromNode1 = inEdge1.GetFromNode();
841         const CDGNode &fromNode2 = inEdge2.GetToNode();
842         return fromNode1.GetNodeId() < fromNode2.GetNodeId();
843     }
844 };
845 }  // namespace maplebe
846 
847 namespace std {
848 template <>
849 struct hash<maplebe::CDGNodeId> {
850     size_t operator()(const maplebe::CDGNodeId &nId) const
851     {
852         return nId;
853     }
854 };
855 
856 template <>
857 struct hash<maplebe::CDGRegionId> {
858     size_t operator()(const maplebe::CDGRegionId &rId) const
859     {
860         return rId;
861     }
862 };
863 }  // namespace std
864 #endif  // MAPLEBE_INCLUDE_CG_CG_CDG_H
865