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*73471bf0Spatrickbool 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*73471bf0Spatrickconst 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*73471bf0SpatrickMachineBasicBlock *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*73471bf0SpatrickMachineBasicBlock *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*73471bf0SpatrickMachineBasicBlock *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