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