| #include "WebAssemblySortRegion.h" | |
| #include "WebAssemblyExceptionInfo.h" | |
| #include "llvm/CodeGen/MachineLoopInfo.h" | |
| using namespace llvm; | |
| using namespace WebAssembly; | |
| namespace llvm { | |
| namespace WebAssembly { | |
| template <> | |
| bool ConcreteSortRegion<MachineLoop>::isLoop() const { | |
| return true; | |
| } | |
| } // end namespace WebAssembly | |
| } // end namespace llvm | |
| const SortRegion *SortRegionInfo::getRegionFor(const MachineBasicBlock *MBB) { | |
| const auto *ML = MLI.getLoopFor(MBB); | |
| const auto *WE = WEI.getExceptionFor(MBB); | |
| if (!ML && !WE) | |
| return nullptr; | |
| // We determine subregion relationship by domination of their headers, i.e., | |
| // if region A's header dominates region B's header, B is a subregion of A. | |
| // WebAssemblyException contains BBs in all its subregions (loops or | |
| // exceptions), but MachineLoop may not, because MachineLoop does not | |
| // contain BBs that don't have a path to its header even if they are | |
| // dominated by its header. So here we should use | |
| // WE->contains(ML->getHeader()), but not ML->contains(WE->getHeader()). | |
| if ((ML && !WE) || (ML && WE && WE->contains(ML->getHeader()))) { | |
| // If the smallest region containing MBB is a loop | |
| auto [It, Inserted] = LoopMap.try_emplace(ML); | |
| if (Inserted) | |
| It->second = std::make_unique<ConcreteSortRegion<MachineLoop>>(ML); | |
| return It->second.get(); | |
| } else { | |
| // If the smallest region containing MBB is an exception | |
| auto [It, Inserted] = ExceptionMap.try_emplace(WE); | |
| if (Inserted) | |
| It->second = | |
| std::make_unique<ConcreteSortRegion<WebAssemblyException>>(WE); | |
| return It->second.get(); | |
| } | |
| } | |
| MachineBasicBlock *SortRegionInfo::getBottom(const SortRegion *R) { | |
| if (R->isLoop()) | |
| return getBottom(MLI.getLoopFor(R->getHeader())); | |
| else | |
| return getBottom(WEI.getExceptionFor(R->getHeader())); | |
| } | |
| MachineBasicBlock *SortRegionInfo::getBottom(const MachineLoop *ML) { | |
| MachineBasicBlock *Bottom = ML->getHeader(); | |
| for (MachineBasicBlock *MBB : ML->blocks()) { | |
| if (MBB->getNumber() > Bottom->getNumber()) | |
| Bottom = MBB; | |
| // MachineLoop does not contain all BBs dominated by its header. BBs that | |
| // don't have a path back to the loop header aren't included. But for the | |
| // purpose of CFG sorting and stackification, we need a bottom BB among all | |
| // BBs that are dominated by the loop header. So we check if there is any | |
| // WebAssemblyException contained in this loop, and computes the most bottom | |
| // BB of them all. | |
| if (MBB->isEHPad()) { | |
| MachineBasicBlock *ExBottom = getBottom(WEI.getExceptionFor(MBB)); | |
| if (ExBottom->getNumber() > Bottom->getNumber()) | |
| Bottom = ExBottom; | |
| } | |
| } | |
| return Bottom; | |
| } | |
| MachineBasicBlock *SortRegionInfo::getBottom(const WebAssemblyException *WE) { | |
| MachineBasicBlock *Bottom = WE->getHeader(); | |
| for (MachineBasicBlock *MBB : WE->blocks()) | |
| if (MBB->getNumber() > Bottom->getNumber()) | |
| Bottom = MBB; | |
| return Bottom; | |
| } |