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