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