#include "WebAssemblySortRegion.h" #include "WebAssemblyExceptionInfo.h" #include "llvm/CodeGen/MachineLoopInfo.h" using namespace llvm; using namespace WebAssembly; namespace llvm { namespace WebAssembly { template <> bool ConcreteSortRegion::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 if (LoopMap.count(ML)) return LoopMap[ML].get(); LoopMap[ML] = std::make_unique>(ML); return LoopMap[ML].get(); } else { // If the smallest region containing MBB is an exception if (ExceptionMap.count(WE)) return ExceptionMap[WE].get(); ExceptionMap[WE] = std::make_unique>(WE); return ExceptionMap[WE].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; }