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