xref: /src/contrib/llvm-project/llvm/lib/Target/WebAssembly/WebAssemblySortRegion.cpp (revision e8d8bef961a50d4dc22501cde4fb9fb0be1b2532)
1b60736ecSDimitry Andric #include "WebAssemblySortRegion.h"
2b60736ecSDimitry Andric #include "WebAssemblyExceptionInfo.h"
3b60736ecSDimitry Andric #include "llvm/CodeGen/MachineLoopInfo.h"
4b60736ecSDimitry Andric 
5b60736ecSDimitry Andric using namespace llvm;
6b60736ecSDimitry Andric using namespace WebAssembly;
7b60736ecSDimitry Andric 
8b60736ecSDimitry Andric namespace llvm {
9b60736ecSDimitry Andric namespace WebAssembly {
10b60736ecSDimitry Andric template <>
isLoop() const11b60736ecSDimitry Andric bool ConcreteSortRegion<MachineLoop>::isLoop() const {
12b60736ecSDimitry Andric   return true;
13b60736ecSDimitry Andric }
14b60736ecSDimitry Andric } // end namespace WebAssembly
15b60736ecSDimitry Andric } // end namespace llvm
16b60736ecSDimitry Andric 
getRegionFor(const MachineBasicBlock * MBB)17b60736ecSDimitry Andric const SortRegion *SortRegionInfo::getRegionFor(const MachineBasicBlock *MBB) {
18b60736ecSDimitry Andric   const auto *ML = MLI.getLoopFor(MBB);
19b60736ecSDimitry Andric   const auto *WE = WEI.getExceptionFor(MBB);
20b60736ecSDimitry Andric   if (!ML && !WE)
21b60736ecSDimitry Andric     return nullptr;
22b60736ecSDimitry Andric   // We determine subregion relationship by domination of their headers, i.e.,
23b60736ecSDimitry Andric   // if region A's header dominates region B's header, B is a subregion of A.
24b60736ecSDimitry Andric   // WebAssemblyException contains BBs in all its subregions (loops or
25b60736ecSDimitry Andric   // exceptions), but MachineLoop may not, because MachineLoop does not
26b60736ecSDimitry Andric   // contain BBs that don't have a path to its header even if they are
27b60736ecSDimitry Andric   // dominated by its header. So here we should use
28b60736ecSDimitry Andric   // WE->contains(ML->getHeader()), but not ML->contains(WE->getHeader()).
29b60736ecSDimitry Andric   if ((ML && !WE) || (ML && WE && WE->contains(ML->getHeader()))) {
30b60736ecSDimitry Andric     // If the smallest region containing MBB is a loop
31b60736ecSDimitry Andric     if (LoopMap.count(ML))
32b60736ecSDimitry Andric       return LoopMap[ML].get();
33b60736ecSDimitry Andric     LoopMap[ML] = std::make_unique<ConcreteSortRegion<MachineLoop>>(ML);
34b60736ecSDimitry Andric     return LoopMap[ML].get();
35b60736ecSDimitry Andric   } else {
36b60736ecSDimitry Andric     // If the smallest region containing MBB is an exception
37b60736ecSDimitry Andric     if (ExceptionMap.count(WE))
38b60736ecSDimitry Andric       return ExceptionMap[WE].get();
39b60736ecSDimitry Andric     ExceptionMap[WE] =
40b60736ecSDimitry Andric         std::make_unique<ConcreteSortRegion<WebAssemblyException>>(WE);
41b60736ecSDimitry Andric     return ExceptionMap[WE].get();
42b60736ecSDimitry Andric   }
43b60736ecSDimitry Andric }
44b60736ecSDimitry Andric 
getBottom(const SortRegion * R)45b60736ecSDimitry Andric MachineBasicBlock *SortRegionInfo::getBottom(const SortRegion *R) {
46b60736ecSDimitry Andric   if (R->isLoop())
47b60736ecSDimitry Andric     return getBottom(MLI.getLoopFor(R->getHeader()));
48b60736ecSDimitry Andric   else
49b60736ecSDimitry Andric     return getBottom(WEI.getExceptionFor(R->getHeader()));
50b60736ecSDimitry Andric }
51b60736ecSDimitry Andric 
getBottom(const MachineLoop * ML)52b60736ecSDimitry Andric MachineBasicBlock *SortRegionInfo::getBottom(const MachineLoop *ML) {
53b60736ecSDimitry Andric   MachineBasicBlock *Bottom = ML->getHeader();
54b60736ecSDimitry Andric   for (MachineBasicBlock *MBB : ML->blocks()) {
55b60736ecSDimitry Andric     if (MBB->getNumber() > Bottom->getNumber())
56b60736ecSDimitry Andric       Bottom = MBB;
57b60736ecSDimitry Andric     // MachineLoop does not contain all BBs dominated by its header. BBs that
58b60736ecSDimitry Andric     // don't have a path back to the loop header aren't included. But for the
59b60736ecSDimitry Andric     // purpose of CFG sorting and stackification, we need a bottom BB among all
60b60736ecSDimitry Andric     // BBs that are dominated by the loop header. So we check if there is any
61b60736ecSDimitry Andric     // WebAssemblyException contained in this loop, and computes the most bottom
62b60736ecSDimitry Andric     // BB of them all.
63b60736ecSDimitry Andric     if (MBB->isEHPad()) {
64b60736ecSDimitry Andric       MachineBasicBlock *ExBottom = getBottom(WEI.getExceptionFor(MBB));
65b60736ecSDimitry Andric       if (ExBottom->getNumber() > Bottom->getNumber())
66b60736ecSDimitry Andric         Bottom = ExBottom;
67b60736ecSDimitry Andric     }
68b60736ecSDimitry Andric   }
69b60736ecSDimitry Andric   return Bottom;
70b60736ecSDimitry Andric }
71b60736ecSDimitry Andric 
getBottom(const WebAssemblyException * WE)72b60736ecSDimitry Andric MachineBasicBlock *SortRegionInfo::getBottom(const WebAssemblyException *WE) {
73b60736ecSDimitry Andric   MachineBasicBlock *Bottom = WE->getHeader();
74b60736ecSDimitry Andric   for (MachineBasicBlock *MBB : WE->blocks())
75b60736ecSDimitry Andric     if (MBB->getNumber() > Bottom->getNumber())
76b60736ecSDimitry Andric       Bottom = MBB;
77b60736ecSDimitry Andric   return Bottom;
78b60736ecSDimitry Andric }
79