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 Andricbool 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 Andricconst 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 AndricMachineBasicBlock *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 AndricMachineBasicBlock *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 AndricMachineBasicBlock *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