• 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 MAPLEBE_INCLUDE_CG_CGBB_H
17 #define MAPLEBE_INCLUDE_CG_CGBB_H
18 
19 #include "isa.h"
20 #include "insn.h"
21 #include "sparse_datainfo.h"
22 
23 /* Maple IR headers */
24 #include "mir_nodes.h"
25 #include "mir_symbol.h"
26 
27 /* Maple MP header */
28 #include "mempool_allocator.h"
29 #include "maple_phase_manager.h"
30 
31 namespace maplebe {
32 /* For get bb */
33 #define FIRST_BB_OF_FUNC(FUNC) ((FUNC)->GetFirstBB())
34 #define LAST_BB_OF_FUNC(FUNC) ((FUNC)->GetLastBB())
35 
36 /* For iterating over basic blocks. */
37 #define FOR_BB_BETWEEN(BASE, FROM, TO, DIR) for (BB * (BASE) = (FROM); (BASE) != (TO); (BASE) = (BASE)->DIR())
38 #define FOR_BB_BETWEEN_CONST(BASE, FROM, TO, DIR) \
39     for (const BB *(BASE) = (FROM); (BASE) != (TO); (BASE) = (BASE)->DIR())
40 
41 #define FOR_ALL_BB_CONST(BASE, FUNC) FOR_BB_BETWEEN_CONST(BASE, FIRST_BB_OF_FUNC(FUNC), nullptr, GetNext)
42 #define FOR_ALL_BB(BASE, FUNC) FOR_BB_BETWEEN(BASE, FIRST_BB_OF_FUNC(FUNC), nullptr, GetNext)
43 #define FOR_ALL_BB_REV(BASE, FUNC) FOR_BB_BETWEEN(BASE, LAST_BB_OF_FUNC(FUNC), nullptr, GetPrev)
44 
45 /* For get insn */
46 #define FIRST_INSN(BLOCK) (BLOCK)->GetFirstInsn()
47 #define LAST_INSN(BLOCK) (BLOCK)->GetLastInsn()
48 #define NEXT_INSN(INSN) (INSN)->GetNext()
49 #define PREV_INSN(INSN) (INSN)->GetPrev()
50 
51 /* For iterating over insns in basic block. */
52 #define FOR_INSN_BETWEEN(INSN, FROM, TO, DIR) \
53     for (Insn * (INSN) = (FROM); (INSN) != nullptr && (INSN) != (TO); (INSN) = (INSN)->DIR)
54 
55 #define FOR_BB_INSNS(INSN, BLOCK) for (Insn * (INSN) = FIRST_INSN(BLOCK); (INSN) != nullptr; (INSN) = (INSN)->GetNext())
56 #define FOR_BB_INSNS_CONST(INSN, BLOCK) \
57     for (const Insn *(INSN) = FIRST_INSN(BLOCK); (INSN) != nullptr; (INSN) = (INSN)->GetNext())
58 
59 #define FOR_BB_INSNS_REV(INSN, BLOCK) \
60     for (Insn * (INSN) = LAST_INSN(BLOCK); (INSN) != nullptr; (INSN) = (INSN)->GetPrev())
61 
62 /* For iterating over insns in basic block when we might remove the current insn. */
63 #define FOR_BB_INSNS_SAFE(INSN, BLOCK, NEXT)                                                                 \
64     for (Insn * (INSN) = FIRST_INSN(BLOCK), *(NEXT) = (INSN) ? NEXT_INSN(INSN) : nullptr; (INSN) != nullptr; \
65          (INSN) = (NEXT), (NEXT) = (INSN) ? NEXT_INSN(INSN) : nullptr)
66 
67 #define FOR_BB_INSNS_REV_SAFE(INSN, BLOCK, NEXT)                                                            \
68     for (Insn * (INSN) = LAST_INSN(BLOCK), *(NEXT) = (INSN) ? PREV_INSN(INSN) : nullptr; (INSN) != nullptr; \
69          (INSN) = (NEXT), (NEXT) = (INSN) ? PREV_INSN(INSN) : nullptr)
70 
71 class CGFuncLoops;
72 class CGFunc;
73 
74 class BB {
75 public:
76     enum BBKind : uint8 {
77         kBBFallthru, /* default */
78         kBBIf,       /* conditional branch */
79         kBBGoto,     /* unconditional branch */
80         kBBIgoto,
81         kBBReturn,
82         kBBIntrinsic, /* BB created by inlining intrinsics; shares a lot with BB_if */
83         kBBRangeGoto,
84         kBBThrow, /* For call __java_throw_* and call exit, which will run out of function. */
85         kBBLast
86     };
87 
BB(uint32 bbID,MapleAllocator & mallocator)88     BB(uint32 bbID, MapleAllocator &mallocator)
89         : id(bbID),
90           kind(kBBFallthru), /* kBBFallthru default kind */
91           labIdx(MIRLabelTable::GetDummyLabel()),
92           preds(mallocator.Adapter()),
93           succs(mallocator.Adapter()),
94           ehPreds(mallocator.Adapter()),
95           ehSuccs(mallocator.Adapter()),
96           loopPreds(mallocator.Adapter()),
97           loopSuccs(mallocator.Adapter()),
98           liveInRegNO(mallocator.Adapter()),
99           liveOutRegNO(mallocator.Adapter()),
100           callInsns(mallocator.Adapter()),
101           rangeGotoLabelVec(mallocator.Adapter()),
102           phiInsnList(mallocator.Adapter())
103     {
104     }
105 
106     virtual ~BB() = default;
107 
Clone(MemPool & memPool)108     virtual BB *Clone(MemPool &memPool) const
109     {
110         BB *bb = memPool.Clone<BB>(*this);
111         return bb;
112     }
113 
114     void Dump() const;
115     bool IsCommentBB() const;
116     bool IsEmptyOrCommentOnly() const;
117     bool IsSoloGoto() const;
118     BB *GetValidPrev();
119 
IsEmpty()120     bool IsEmpty() const
121     {
122         if (lastInsn == nullptr) {
123             CHECK_FATAL(firstInsn == nullptr, "firstInsn must be nullptr");
124             return true;
125         } else {
126             CHECK_FATAL(firstInsn != nullptr, "firstInsn must not be nullptr");
127             return false;
128         }
129     }
130 
GetKindName()131     const std::string &GetKindName() const
132     {
133         DEBUG_ASSERT(kind < kBBLast, "out of range in GetKindName");
134         return bbNames[kind];
135     }
136 
SetKind(BBKind bbKind)137     void SetKind(BBKind bbKind)
138     {
139         kind = bbKind;
140     }
141 
GetKind()142     BBKind GetKind() const
143     {
144         return kind;
145     }
146 
AddLabel(LabelIdx idx)147     void AddLabel(LabelIdx idx)
148     {
149         labIdx = idx;
150     }
151 
AppendBB(BB & bb)152     void AppendBB(BB &bb)
153     {
154         bb.prev = this;
155         bb.next = next;
156         if (next != nullptr) {
157             next->prev = &bb;
158         }
159         next = &bb;
160     }
161 
PrependBB(BB & bb)162     void PrependBB(BB &bb)
163     {
164         bb.next = this;
165         bb.prev = this->prev;
166         if (this->prev != nullptr) {
167             this->prev->next = &bb;
168         }
169         this->prev = &bb;
170     }
171 
172     Insn *InsertInsnBefore(Insn &existing, Insn &newInsn);
173 
174     /* returns newly inserted instruction */
175     Insn *InsertInsnAfter(Insn &existing, Insn &newInsn);
176 
InsertInsnBegin(Insn & insn)177     void InsertInsnBegin(Insn &insn)
178     {
179         if (lastInsn == nullptr) {
180             firstInsn = lastInsn = &insn;
181             insn.SetNext(nullptr);
182             insn.SetPrev(nullptr);
183             insn.SetBB(this);
184         } else {
185             InsertInsnBefore(*firstInsn, insn);
186         }
187     }
188 
AppendInsn(Insn & insn)189     void AppendInsn(Insn &insn)
190     {
191         if (firstInsn != nullptr && lastInsn != nullptr) {
192             InsertInsnAfter(*lastInsn, insn);
193         } else {
194             firstInsn = lastInsn = &insn;
195             insn.SetNext(nullptr);
196             insn.SetPrev(nullptr);
197             insn.SetBB(this);
198         }
199         internalFlag1++;
200     }
201 
202     void ReplaceInsn(Insn &insn, Insn &newInsn);
203 
204     void RemoveInsn(Insn &insn);
205 
206     void RemoveInsnPair(Insn &insn, const Insn &nextInsn);
207 
208     void RemoveInsnSequence(Insn &insn, const Insn &nextInsn);
209 
210     /* append all insns from bb into this bb */
211     void AppendBBInsns(BB &bb);
212 
213     /* append all insns from bb into this bb */
214     void InsertAtBeginning(BB &bb);
215     void InsertAtEnd(BB &bb);
216     void InsertAtEndMinus1(BB &bb);
217 
218     /* clear BB but don't remove insns of this */
ClearInsns()219     void ClearInsns()
220     {
221         firstInsn = lastInsn = nullptr;
222     }
223 
NumPreds()224     uint32 NumPreds() const
225     {
226         return static_cast<uint32>(preds.size());
227     }
228 
IsPredecessor(const BB & predBB)229     bool IsPredecessor(const BB &predBB)
230     {
231         for (const BB *bb : preds) {
232             if (bb == &predBB) {
233                 return true;
234             }
235         }
236         return false;
237     }
238 
IsBackEdgeDest()239     bool IsBackEdgeDest() const
240     {
241         return !loopPreds.empty();
242     }
243 
RemoveFromPredecessorList(const BB & bb)244     void RemoveFromPredecessorList(const BB &bb)
245     {
246         for (auto i = preds.begin(); i != preds.end(); ++i) {
247             if (*i == &bb) {
248                 preds.erase(i);
249                 return;
250             }
251         }
252         CHECK_FATAL(false, "request to remove a non-existent element?");
253     }
254 
RemoveFromSuccessorList(const BB & bb)255     void RemoveFromSuccessorList(const BB &bb)
256     {
257         for (auto i = succs.begin(); i != succs.end(); ++i) {
258             if (*i == &bb) {
259                 succs.erase(i);
260                 return;
261             }
262         }
263         CHECK_FATAL(false, "request to remove a non-existent element?");
264     }
265 
NumSuccs()266     uint32 NumSuccs() const
267     {
268         return static_cast<uint32>(succs.size());
269     }
270 
HasCall()271     bool HasCall() const
272     {
273         return hasCall;
274     }
275 
SetHasCall()276     void SetHasCall()
277     {
278         hasCall = true;
279     }
280 
281     /* Number of instructions excluding DbgInsn and comments */
282     int32 NumInsn() const;
GetId()283     uint32 GetId() const
284     {
285         return id;
286     }
GetLevel()287     uint32 GetLevel() const
288     {
289         return level;
290     }
SetLevel(uint32 arg)291     void SetLevel(uint32 arg)
292     {
293         level = arg;
294     }
GetFrequency()295     uint32 GetFrequency() const
296     {
297         return frequency;
298     }
SetFrequency(uint32 arg)299     void SetFrequency(uint32 arg)
300     {
301         frequency = arg;
302     }
GetNext()303     BB *GetNext()
304     {
305         return next;
306     }
GetNext()307     const BB *GetNext() const
308     {
309         return next;
310     }
GetPrev()311     BB *GetPrev()
312     {
313         return prev;
314     }
GetPrev()315     const BB *GetPrev() const
316     {
317         return prev;
318     }
SetNext(BB * arg)319     void SetNext(BB *arg)
320     {
321         next = arg;
322     }
SetPrev(BB * arg)323     void SetPrev(BB *arg)
324     {
325         prev = arg;
326     }
GetLabIdx()327     LabelIdx GetLabIdx() const
328     {
329         return labIdx;
330     }
SetLabIdx(LabelIdx arg)331     void SetLabIdx(LabelIdx arg)
332     {
333         labIdx = arg;
334     }
GetFirstStmt()335     StmtNode *GetFirstStmt()
336     {
337         return firstStmt;
338     }
GetFirstStmt()339     const StmtNode *GetFirstStmt() const
340     {
341         return firstStmt;
342     }
SetFirstStmt(StmtNode & arg)343     void SetFirstStmt(StmtNode &arg)
344     {
345         firstStmt = &arg;
346     }
GetLastStmt()347     StmtNode *GetLastStmt()
348     {
349         return lastStmt;
350     }
GetLastStmt()351     const StmtNode *GetLastStmt() const
352     {
353         return lastStmt;
354     }
SetLastStmt(StmtNode & arg)355     void SetLastStmt(StmtNode &arg)
356     {
357         lastStmt = &arg;
358     }
GetFirstInsn()359     Insn *GetFirstInsn()
360     {
361         return firstInsn;
362     }
GetFirstInsn()363     const Insn *GetFirstInsn() const
364     {
365         return firstInsn;
366     }
367 
SetFirstInsn(Insn * arg)368     void SetFirstInsn(Insn *arg)
369     {
370         firstInsn = arg;
371     }
GetFirstMachineInsn()372     Insn *GetFirstMachineInsn()
373     {
374         FOR_BB_INSNS(insn, this) {
375             if (insn->IsMachineInstruction()) {
376                 return insn;
377             }
378         }
379         return nullptr;
380     }
GetLastMachineInsn()381     Insn *GetLastMachineInsn()
382     {
383         FOR_BB_INSNS_REV(insn, this) {
384             if (insn->IsMachineInstruction()) {
385                 return insn;
386             }
387         }
388         return nullptr;
389     }
GetLastInsn()390     Insn *GetLastInsn()
391     {
392         return lastInsn;
393     }
GetLastInsn()394     const Insn *GetLastInsn() const
395     {
396         return lastInsn;
397     }
SetLastInsn(Insn * arg)398     void SetLastInsn(Insn *arg)
399     {
400         lastInsn = arg;
401     }
IsLastInsn(const Insn * insn)402     bool IsLastInsn(const Insn *insn) const
403     {
404         return (lastInsn == insn);
405     }
InsertPred(const MapleList<BB * >::iterator & it,BB & bb)406     void InsertPred(const MapleList<BB *>::iterator &it, BB &bb)
407     {
408         preds.insert(it, &bb);
409     }
InsertSucc(const MapleList<BB * >::iterator & it,BB & bb)410     void InsertSucc(const MapleList<BB *>::iterator &it, BB &bb)
411     {
412         succs.insert(it, &bb);
413     }
GetPreds()414     const MapleList<BB *> &GetPreds() const
415     {
416         return preds;
417     }
GetSuccs()418     const MapleList<BB *> &GetSuccs() const
419     {
420         return succs;
421     }
GetEhPreds()422     const MapleList<BB *> &GetEhPreds() const
423     {
424         return ehPreds;
425     }
GetEhSuccs()426     const MapleList<BB *> &GetEhSuccs() const
427     {
428         return ehSuccs;
429     }
GetLoopPreds()430     const MapleList<BB *> &GetLoopPreds() const
431     {
432         return loopPreds;
433     }
GetLoopSuccs()434     MapleList<BB *> &GetLoopSuccs()
435     {
436         return loopSuccs;
437     }
GetLoopSuccs()438     const MapleList<BB *> &GetLoopSuccs() const
439     {
440         return loopSuccs;
441     }
GetPredsBegin()442     MapleList<BB *>::iterator GetPredsBegin()
443     {
444         return preds.begin();
445     }
GetSuccsBegin()446     MapleList<BB *>::iterator GetSuccsBegin()
447     {
448         return succs.begin();
449     }
GetEhPredsBegin()450     MapleList<BB *>::iterator GetEhPredsBegin()
451     {
452         return ehPreds.begin();
453     }
GetLoopSuccsBegin()454     MapleList<BB *>::iterator GetLoopSuccsBegin()
455     {
456         return loopSuccs.begin();
457     }
GetPredsEnd()458     MapleList<BB *>::iterator GetPredsEnd()
459     {
460         return preds.end();
461     }
GetSuccsEnd()462     MapleList<BB *>::iterator GetSuccsEnd()
463     {
464         return succs.end();
465     }
GetEhPredsEnd()466     MapleList<BB *>::iterator GetEhPredsEnd()
467     {
468         return ehPreds.end();
469     }
GetLoopSuccsEnd()470     MapleList<BB *>::iterator GetLoopSuccsEnd()
471     {
472         return loopSuccs.end();
473     }
PushBackPreds(BB & bb)474     void PushBackPreds(BB &bb)
475     {
476         preds.push_back(&bb);
477     }
PushBackSuccs(BB & bb)478     void PushBackSuccs(BB &bb)
479     {
480         succs.push_back(&bb);
481     }
PushBackEhPreds(BB & bb)482     void PushBackEhPreds(BB &bb)
483     {
484         ehPreds.push_back(&bb);
485     }
PushBackEhSuccs(BB & bb)486     void PushBackEhSuccs(BB &bb)
487     {
488         ehSuccs.push_back(&bb);
489     }
PushBackLoopPreds(BB & bb)490     void PushBackLoopPreds(BB &bb)
491     {
492         loopPreds.push_back(&bb);
493     }
PushBackLoopSuccs(BB & bb)494     void PushBackLoopSuccs(BB &bb)
495     {
496         loopSuccs.push_back(&bb);
497     }
PushFrontPreds(BB & bb)498     void PushFrontPreds(BB &bb)
499     {
500         preds.push_front(&bb);
501     }
PushFrontSuccs(BB & bb)502     void PushFrontSuccs(BB &bb)
503     {
504         succs.push_front(&bb);
505     }
ErasePreds(MapleList<BB * >::iterator it)506     void ErasePreds(MapleList<BB *>::iterator it)
507     {
508         preds.erase(it);
509     }
EraseSuccs(MapleList<BB * >::iterator it)510     void EraseSuccs(MapleList<BB *>::iterator it)
511     {
512         succs.erase(it);
513     }
RemovePreds(BB & bb)514     void RemovePreds(BB &bb)
515     {
516         preds.remove(&bb);
517     }
RemoveSuccs(BB & bb)518     void RemoveSuccs(BB &bb)
519     {
520         succs.remove(&bb);
521     }
RemoveEhPreds(BB & bb)522     void RemoveEhPreds(BB &bb)
523     {
524         ehPreds.remove(&bb);
525     }
RemoveEhSuccs(BB & bb)526     void RemoveEhSuccs(BB &bb)
527     {
528         ehSuccs.remove(&bb);
529     }
ClearPreds()530     void ClearPreds()
531     {
532         preds.clear();
533     }
ClearSuccs()534     void ClearSuccs()
535     {
536         succs.clear();
537     }
ClearEhPreds()538     void ClearEhPreds()
539     {
540         ehPreds.clear();
541     }
ClearEhSuccs()542     void ClearEhSuccs()
543     {
544         ehSuccs.clear();
545     }
ClearLoopPreds()546     void ClearLoopPreds()
547     {
548         loopPreds.clear();
549     }
ClearLoopSuccs()550     void ClearLoopSuccs()
551     {
552         loopSuccs.clear();
553     }
GetLiveInRegNO()554     const MapleSet<regno_t> &GetLiveInRegNO() const
555     {
556         return liveInRegNO;
557     }
GetLiveInRegNO()558     MapleSet<regno_t> &GetLiveInRegNO()
559     {
560         return liveInRegNO;
561     }
InsertLiveInRegNO(regno_t arg)562     void InsertLiveInRegNO(regno_t arg)
563     {
564         (void)liveInRegNO.insert(arg);
565     }
EraseLiveInRegNO(MapleSet<regno_t>::iterator it)566     void EraseLiveInRegNO(MapleSet<regno_t>::iterator it)
567     {
568         liveInRegNO.erase(it);
569     }
EraseLiveInRegNO(regno_t arg)570     void EraseLiveInRegNO(regno_t arg)
571     {
572         liveInRegNO.erase(arg);
573     }
ClearLiveInRegNO()574     void ClearLiveInRegNO()
575     {
576         liveInRegNO.clear();
577     }
GetLiveOutRegNO()578     const MapleSet<regno_t> &GetLiveOutRegNO() const
579     {
580         return liveOutRegNO;
581     }
GetLiveOutRegNO()582     MapleSet<regno_t> &GetLiveOutRegNO()
583     {
584         return liveOutRegNO;
585     }
InsertLiveOutRegNO(regno_t arg)586     void InsertLiveOutRegNO(regno_t arg)
587     {
588         (void)liveOutRegNO.insert(arg);
589     }
EraseLiveOutRegNO(MapleSet<regno_t>::iterator it)590     void EraseLiveOutRegNO(MapleSet<regno_t>::iterator it)
591     {
592         liveOutRegNO.erase(it);
593     }
ClearLiveOutRegNO()594     void ClearLiveOutRegNO()
595     {
596         liveOutRegNO.clear();
597     }
GetLoop()598     CGFuncLoops *GetLoop() const
599     {
600         return loop;
601     }
SetLoop(CGFuncLoops & arg)602     void SetLoop(CGFuncLoops &arg)
603     {
604         loop = &arg;
605     }
GetLiveInChange()606     bool GetLiveInChange() const
607     {
608         return liveInChange;
609     }
SetLiveInChange(bool arg)610     void SetLiveInChange(bool arg)
611     {
612         liveInChange = arg;
613     }
GetCritical()614     bool GetCritical() const
615     {
616         return isCritical;
617     }
SetCritical(bool arg)618     void SetCritical(bool arg)
619     {
620         isCritical = arg;
621     }
622     bool HasCriticalEdge();
GetInsertUse()623     bool GetInsertUse() const
624     {
625         return insertUse;
626     }
SetInsertUse(bool arg)627     void SetInsertUse(bool arg)
628     {
629         insertUse = arg;
630     }
IsUnreachable()631     bool IsUnreachable() const
632     {
633         return unreachable;
634     }
SetUnreachable(bool arg)635     void SetUnreachable(bool arg)
636     {
637         unreachable = arg;
638     }
IsWontExit()639     bool IsWontExit() const
640     {
641         return wontExit;
642     }
SetWontExit(bool arg)643     void SetWontExit(bool arg)
644     {
645         wontExit = arg;
646     }
SetFastPath(bool arg)647     void SetFastPath(bool arg)
648     {
649         fastPath = arg;
650     }
IsCatch()651     bool IsCatch() const
652     {
653         return isCatch;
654     }
SetIsCatch(bool arg)655     void SetIsCatch(bool arg)
656     {
657         isCatch = arg;
658     }
IsCleanup()659     bool IsCleanup() const
660     {
661         return isCleanup;
662     }
SetIsCleanup(bool arg)663     void SetIsCleanup(bool arg)
664     {
665         isCleanup = arg;
666     }
IsProEpilog()667     bool IsProEpilog() const
668     {
669         return isProEpilog;
670     }
SetIsProEpilog(bool arg)671     void SetIsProEpilog(bool arg)
672     {
673         isProEpilog = arg;
674     }
IsLabelTaken()675     bool IsLabelTaken() const
676     {
677         return labelTaken;
678     }
SetLabelTaken()679     void SetLabelTaken()
680     {
681         labelTaken = true;
682     }
GetHasCfi()683     bool GetHasCfi() const
684     {
685         return hasCfi;
686     }
SetHasCfi()687     void SetHasCfi()
688     {
689         hasCfi = true;
690     }
GetInternalFlag1()691     long GetInternalFlag1() const
692     {
693         return internalFlag1;
694     }
SetInternalFlag1(long arg)695     void SetInternalFlag1(long arg)
696     {
697         internalFlag1 = arg;
698     }
GetInternalFlag2()699     long GetInternalFlag2() const
700     {
701         return internalFlag2;
702     }
SetInternalFlag2(long arg)703     void SetInternalFlag2(long arg)
704     {
705         internalFlag2 = arg;
706     }
GetInternalFlag3()707     long GetInternalFlag3() const
708     {
709         return internalFlag3;
710     }
SetInternalFlag3(long arg)711     void SetInternalFlag3(long arg)
712     {
713         internalFlag3 = arg;
714     }
IsAtomicBuiltInBB()715     bool IsAtomicBuiltInBB() const
716     {
717         return isAtomicBuiltIn;
718     }
SetAtomicBuiltIn()719     void SetAtomicBuiltIn()
720     {
721         isAtomicBuiltIn = true;
722     }
GetCallInsns()723     const MapleList<Insn *> &GetCallInsns() const
724     {
725         return callInsns;
726     }
PushBackCallInsns(Insn & insn)727     void PushBackCallInsns(Insn &insn)
728     {
729         callInsns.push_back(&insn);
730     }
ClearCallInsns()731     void ClearCallInsns()
732     {
733         callInsns.clear();
734     }
GetRangeGotoLabelVec()735     const MapleVector<LabelIdx> &GetRangeGotoLabelVec() const
736     {
737         return rangeGotoLabelVec;
738     }
SetRangeGotoLabel(uint32 index,LabelIdx labelIdx)739     void SetRangeGotoLabel(uint32 index, LabelIdx labelIdx)
740     {
741         rangeGotoLabelVec[index] = labelIdx;
742     }
PushBackRangeGotoLabel(LabelIdx labelIdx)743     void PushBackRangeGotoLabel(LabelIdx labelIdx)
744     {
745         rangeGotoLabelVec.emplace_back(labelIdx);
746     }
AddPhiInsn(regno_t regNO,Insn & insn)747     void AddPhiInsn(regno_t regNO, Insn &insn)
748     {
749         DEBUG_ASSERT(!phiInsnList.count(regNO), "repeat phiInsn");
750         phiInsnList.emplace(std::pair<regno_t, Insn *>(regNO, &insn));
751     }
RemovePhiInsn(regno_t regNO)752     void RemovePhiInsn(regno_t regNO)
753     {
754         DEBUG_ASSERT(phiInsnList.count(regNO), "no such insn");
755         phiInsnList.erase(regNO);
756     }
HasPhiInsn(regno_t regNO)757     bool HasPhiInsn(regno_t regNO)
758     {
759         return phiInsnList.find(regNO) != phiInsnList.end();
760     }
GetPhiInsns()761     MapleMap<regno_t, Insn *> &GetPhiInsns()
762     {
763         return phiInsnList;
764     }
765     bool IsInPhiList(regno_t regNO);
766     bool IsInPhiDef(regno_t regNO);
GetFirstLoc()767     const Insn *GetFirstLoc() const
768     {
769         return firstLoc;
770     }
SetFirstLoc(const Insn & arg)771     void SetFirstLoc(const Insn &arg)
772     {
773         firstLoc = &arg;
774     }
GetLastLoc()775     const Insn *GetLastLoc() const
776     {
777         return lastLoc;
778     }
SetLastLoc(const Insn * arg)779     void SetLastLoc(const Insn *arg)
780     {
781         lastLoc = arg;
782     }
GetLiveIn()783     SparseDataInfo *GetLiveIn()
784     {
785         return liveIn;
786     }
GetLiveIn()787     const SparseDataInfo *GetLiveIn() const
788     {
789         return liveIn;
790     }
SetLiveIn(SparseDataInfo & arg)791     void SetLiveIn(SparseDataInfo &arg)
792     {
793         liveIn = &arg;
794     }
SetLiveInBit(uint32 arg)795     void SetLiveInBit(uint32 arg) const
796     {
797         liveIn->SetBit(arg);
798     }
SetLiveInInfo(const SparseDataInfo & arg)799     void SetLiveInInfo(const SparseDataInfo &arg) const
800     {
801         *liveIn = arg;
802     }
LiveInOrBits(const SparseDataInfo & arg)803     void LiveInOrBits(const SparseDataInfo &arg) const
804     {
805         liveIn->OrBits(arg);
806     }
LiveInEnlargeCapacity(uint32 arg)807     void LiveInEnlargeCapacity(uint32 arg) const
808     {
809         liveIn->EnlargeCapacityToAdaptSize(arg);
810     }
LiveInClearDataInfo()811     void LiveInClearDataInfo()
812     {
813         liveIn->ClearDataInfo();
814         liveIn = nullptr;
815     }
GetLiveOut()816     SparseDataInfo *GetLiveOut()
817     {
818         return liveOut;
819     }
GetLiveOut()820     const SparseDataInfo *GetLiveOut() const
821     {
822         return liveOut;
823     }
SetLiveOut(SparseDataInfo & arg)824     void SetLiveOut(SparseDataInfo &arg)
825     {
826         liveOut = &arg;
827     }
SetLiveOutBit(uint32 arg)828     void SetLiveOutBit(uint32 arg) const
829     {
830         liveOut->SetBit(arg);
831     }
LiveOutOrBits(const SparseDataInfo & arg)832     void LiveOutOrBits(const SparseDataInfo &arg) const
833     {
834         liveOut->OrBits(arg);
835     }
LiveOutEnlargeCapacity(uint32 arg)836     void LiveOutEnlargeCapacity(uint32 arg) const
837     {
838         liveOut->EnlargeCapacityToAdaptSize(arg);
839     }
LiveOutClearDataInfo()840     void LiveOutClearDataInfo()
841     {
842         liveOut->ClearDataInfo();
843         liveOut = nullptr;
844     }
GetDef()845     const SparseDataInfo *GetDef() const
846     {
847         return def;
848     }
SetDef(SparseDataInfo & arg)849     void SetDef(SparseDataInfo &arg)
850     {
851         def = &arg;
852     }
SetDefBit(uint32 arg)853     void SetDefBit(uint32 arg) const
854     {
855         def->SetBit(arg);
856     }
DefResetAllBit()857     void DefResetAllBit() const
858     {
859         def->ResetAllBit();
860     }
DefResetBit(uint32 arg)861     void DefResetBit(uint32 arg) const
862     {
863         def->ResetBit(arg);
864     }
DefClearDataInfo()865     void DefClearDataInfo()
866     {
867         def->ClearDataInfo();
868         def = nullptr;
869     }
GetUse()870     const SparseDataInfo *GetUse() const
871     {
872         return use;
873     }
SetUse(SparseDataInfo & arg)874     void SetUse(SparseDataInfo &arg)
875     {
876         use = &arg;
877     }
SetUseBit(uint32 arg)878     void SetUseBit(uint32 arg) const
879     {
880         use->SetBit(arg);
881     }
UseResetAllBit()882     void UseResetAllBit() const
883     {
884         use->ResetAllBit();
885     }
UseResetBit(uint32 arg)886     void UseResetBit(uint32 arg) const
887     {
888         use->ResetBit(arg);
889     }
UseClearDataInfo()890     void UseClearDataInfo()
891     {
892         use->ClearDataInfo();
893         use = nullptr;
894     }
SetNeedAlign(bool flag)895     void SetNeedAlign(bool flag)
896     {
897         needAlign = flag;
898     }
IsBBNeedAlign()899     bool IsBBNeedAlign() const
900     {
901         return needAlign;
902     }
SetAlignPower(uint32 power)903     void SetAlignPower(uint32 power)
904     {
905         alignPower = power;
906     }
GetAlignPower()907     uint32 GetAlignPower() const
908     {
909         return alignPower;
910     }
SetAlignNopNum(uint32 num)911     void SetAlignNopNum(uint32 num)
912     {
913         alignNopNum = num;
914     }
GetAlignNopNum()915     uint32 GetAlignNopNum() const
916     {
917         return alignNopNum;
918     }
919 
920 private:
921     static const std::string bbNames[kBBLast];
922     uint32 id;
923     uint32 level = 0;
924     uint32 frequency = 0;
925     BB *prev = nullptr; /* Doubly linked list of BBs; */
926     BB *next = nullptr;
927     /* They represent the order in which blocks are to be emitted. */
928     BBKind kind = kBBFallthru; /* The BB's last statement (i.e. lastStmt) determines */
929     /* what type this BB has. By default, kBbFallthru */
930     LabelIdx labIdx;
931     StmtNode *firstStmt = nullptr;
932     StmtNode *lastStmt = nullptr;
933     Insn *firstInsn = nullptr; /* the first instruction */
934     Insn *lastInsn = nullptr;  /* the last instruction */
935     MapleList<BB *> preds;     /* preds, succs represent CFG */
936     MapleList<BB *> succs;
937     MapleList<BB *> ehPreds;
938     MapleList<BB *> ehSuccs;
939     MapleList<BB *> loopPreds;
940     MapleList<BB *> loopSuccs;
941 
942     /* this is for live in out analysis */
943     MapleSet<regno_t> liveInRegNO;
944     MapleSet<regno_t> liveOutRegNO;
945     CGFuncLoops *loop = nullptr;
946     bool liveInChange = false;
947     bool isCritical = false;
948     bool insertUse = false;
949     bool hasCall = false;
950     bool unreachable = false;
951     bool wontExit = false;
952     bool fastPath = false;
953     bool isCatch = false; /* part of the catch bb, true does might also mean it is unreachable */
954     /*
955      * Since isCatch is set early and unreachable detected later, there
956      * are some overlap here.
957      */
958     bool isCleanup = false;   /* true if the bb is cleanup bb. otherwise, false. */
959     bool isProEpilog = false; /* Temporary tag for modifying prolog/epilog bb. */
960     bool labelTaken = false;  /* Block label is taken indirectly and can be used to jump to it. */
961     bool hasCfi = false;      /* bb contain cfi directive. */
962     /*
963      * Different meaning for each data flow analysis.
964      * For HandleFunction(), rough estimate of num of insn created.
965      * For cgbb.cpp, track insn count during code selection.
966      * For cgbb.cpp, bb is traversed during BFS ordering.
967      * For aarchregalloc.cpp, the bb is part of cleanup at end of function.
968      * For aarchcolorra.cpp, the bb is part of cleanup at end of function.
969      *                       also used for live range splitting.
970      * For live analysis, it indicates if bb is cleanupbb.
971      */
972     long internalFlag1 = 0;
973 
974     /*
975      * Different meaning for each data flow analysis.
976      * For cgbb.cpp, bb is levelized to be 1 more than largest predecessor.
977      * For aarchcolorra.cpp, used for live range splitting pruning of bb.
978      */
979     long internalFlag2 = 0;
980 
981     /*
982      * Different meaning for each data flow analysis.
983      * For cgfunc.cpp, it temporarily marks for catch bb discovery.
984      * For live analysis, it indicates if bb is visited.
985      * For peephole, used for live-out checking of bb.
986      */
987     long internalFlag3 = 0;
988     MapleList<Insn *> callInsns;
989     MapleVector<LabelIdx> rangeGotoLabelVec;
990 
991     /* bb support for SSA analysis */
992     MapleMap<regno_t, Insn *> phiInsnList;
993 
994     /* includes Built-in functions for atomic memory access */
995     bool isAtomicBuiltIn = false;
996 
997     const Insn *firstLoc = nullptr;
998     const Insn *lastLoc = nullptr;
999     SparseDataInfo *liveIn = nullptr;
1000     SparseDataInfo *liveOut = nullptr;
1001     SparseDataInfo *def = nullptr;
1002     SparseDataInfo *use = nullptr;
1003 
1004     bool needAlign = false;
1005     uint32 alignPower = 0;
1006     uint32 alignNopNum = 0;
1007 }; /* class BB */
1008 
1009 struct BBIdCmp {
operatorBBIdCmp1010     bool operator()(const BB *lhs, const BB *rhs) const
1011     {
1012         CHECK_FATAL(lhs != nullptr, "null ptr check");
1013         CHECK_FATAL(rhs != nullptr, "null ptr check");
1014         return (lhs->GetId() < rhs->GetId());
1015     }
1016 };
1017 
1018 class Bfs : public AnalysisResult {
1019 public:
Bfs(CGFunc & cgFunc,MemPool & memPool)1020     Bfs(CGFunc &cgFunc, MemPool &memPool)
1021         : AnalysisResult(&memPool),
1022           cgfunc(&cgFunc),
1023           alloc(&memPool),
1024           visitedBBs(alloc.Adapter()),
1025           sortedBBs(alloc.Adapter())
1026     {
1027     }
1028     ~Bfs() = default;
1029 
1030     bool AllPredBBVisited(const BB &bb, long &level) const;
1031     BB *MarkStraightLineBBInBFS(BB *bb);
1032     BB *SearchForStraightLineBBs(BB &bb);
1033     void BFS(BB &curBB);
1034     void ComputeBlockOrder();
1035 
1036     CGFunc *cgfunc;
1037     MapleAllocator alloc;
1038     MapleVector<bool> visitedBBs;
1039     MapleVector<BB *> sortedBBs;
1040 };
1041 
MAPLE_FUNC_PHASE_DECLARE_BEGIN(CgBBSort,CGFunc)1042 MAPLE_FUNC_PHASE_DECLARE_BEGIN(CgBBSort, CGFunc)
1043 Bfs *GetResult()
1044 {
1045     return bfs;
1046 }
1047 Bfs *bfs = nullptr;
1048 OVERRIDE_DEPENDENCE
1049 MAPLE_MODULE_PHASE_DECLARE_END
1050 } /* namespace maplebe */
1051 
1052 #endif /* MAPLEBE_INCLUDE_CG_CGBB_H */
1053