1*e8d8bef9SDimitry Andric //===-- WebAssemblySortRegion.h - WebAssembly Sort SortRegion ----*- C++-*-===// 2*e8d8bef9SDimitry Andric // 3*e8d8bef9SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*e8d8bef9SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*e8d8bef9SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*e8d8bef9SDimitry Andric // 7*e8d8bef9SDimitry Andric //===----------------------------------------------------------------------===// 8*e8d8bef9SDimitry Andric /// 9*e8d8bef9SDimitry Andric /// \file 10*e8d8bef9SDimitry Andric /// \brief This file implements regions used in CFGSort and CFGStackify. 11*e8d8bef9SDimitry Andric /// 12*e8d8bef9SDimitry Andric //===----------------------------------------------------------------------===// 13*e8d8bef9SDimitry Andric 14*e8d8bef9SDimitry Andric #ifndef LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYSORTREGION_H 15*e8d8bef9SDimitry Andric #define LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYSORTREGION_H 16*e8d8bef9SDimitry Andric 17*e8d8bef9SDimitry Andric #include "llvm/ADT/ArrayRef.h" 18*e8d8bef9SDimitry Andric #include "llvm/ADT/DenseMap.h" 19*e8d8bef9SDimitry Andric #include "llvm/ADT/iterator_range.h" 20*e8d8bef9SDimitry Andric 21*e8d8bef9SDimitry Andric namespace llvm { 22*e8d8bef9SDimitry Andric 23*e8d8bef9SDimitry Andric class MachineBasicBlock; 24*e8d8bef9SDimitry Andric class MachineLoop; 25*e8d8bef9SDimitry Andric class MachineLoopInfo; 26*e8d8bef9SDimitry Andric class WebAssemblyException; 27*e8d8bef9SDimitry Andric class WebAssemblyExceptionInfo; 28*e8d8bef9SDimitry Andric 29*e8d8bef9SDimitry Andric namespace WebAssembly { 30*e8d8bef9SDimitry Andric 31*e8d8bef9SDimitry Andric // Wrapper for loops and exceptions 32*e8d8bef9SDimitry Andric class SortRegion { 33*e8d8bef9SDimitry Andric public: 34*e8d8bef9SDimitry Andric virtual ~SortRegion() = default; 35*e8d8bef9SDimitry Andric virtual MachineBasicBlock *getHeader() const = 0; 36*e8d8bef9SDimitry Andric virtual bool contains(const MachineBasicBlock *MBB) const = 0; 37*e8d8bef9SDimitry Andric virtual unsigned getNumBlocks() const = 0; 38*e8d8bef9SDimitry Andric using block_iterator = typename ArrayRef<MachineBasicBlock *>::const_iterator; 39*e8d8bef9SDimitry Andric virtual iterator_range<block_iterator> blocks() const = 0; 40*e8d8bef9SDimitry Andric virtual bool isLoop() const = 0; 41*e8d8bef9SDimitry Andric }; 42*e8d8bef9SDimitry Andric 43*e8d8bef9SDimitry Andric template <typename T> class ConcreteSortRegion : public SortRegion { 44*e8d8bef9SDimitry Andric const T *Unit; 45*e8d8bef9SDimitry Andric 46*e8d8bef9SDimitry Andric public: ConcreteSortRegion(const T * Unit)47*e8d8bef9SDimitry Andric ConcreteSortRegion(const T *Unit) : Unit(Unit) {} getHeader()48*e8d8bef9SDimitry Andric MachineBasicBlock *getHeader() const override { return Unit->getHeader(); } contains(const MachineBasicBlock * MBB)49*e8d8bef9SDimitry Andric bool contains(const MachineBasicBlock *MBB) const override { 50*e8d8bef9SDimitry Andric return Unit->contains(MBB); 51*e8d8bef9SDimitry Andric } getNumBlocks()52*e8d8bef9SDimitry Andric unsigned getNumBlocks() const override { return Unit->getNumBlocks(); } blocks()53*e8d8bef9SDimitry Andric iterator_range<block_iterator> blocks() const override { 54*e8d8bef9SDimitry Andric return Unit->blocks(); 55*e8d8bef9SDimitry Andric } isLoop()56*e8d8bef9SDimitry Andric bool isLoop() const override { return false; } 57*e8d8bef9SDimitry Andric }; 58*e8d8bef9SDimitry Andric 59*e8d8bef9SDimitry Andric // This class has information of nested SortRegions; this is analogous to what 60*e8d8bef9SDimitry Andric // LoopInfo is for loops. 61*e8d8bef9SDimitry Andric class SortRegionInfo { 62*e8d8bef9SDimitry Andric friend class ConcreteSortRegion<MachineLoopInfo>; 63*e8d8bef9SDimitry Andric friend class ConcreteSortRegion<WebAssemblyException>; 64*e8d8bef9SDimitry Andric 65*e8d8bef9SDimitry Andric const MachineLoopInfo &MLI; 66*e8d8bef9SDimitry Andric const WebAssemblyExceptionInfo &WEI; 67*e8d8bef9SDimitry Andric DenseMap<const MachineLoop *, std::unique_ptr<SortRegion>> LoopMap; 68*e8d8bef9SDimitry Andric DenseMap<const WebAssemblyException *, std::unique_ptr<SortRegion>> 69*e8d8bef9SDimitry Andric ExceptionMap; 70*e8d8bef9SDimitry Andric 71*e8d8bef9SDimitry Andric public: SortRegionInfo(const MachineLoopInfo & MLI,const WebAssemblyExceptionInfo & WEI)72*e8d8bef9SDimitry Andric SortRegionInfo(const MachineLoopInfo &MLI, 73*e8d8bef9SDimitry Andric const WebAssemblyExceptionInfo &WEI) 74*e8d8bef9SDimitry Andric : MLI(MLI), WEI(WEI) {} 75*e8d8bef9SDimitry Andric 76*e8d8bef9SDimitry Andric // Returns a smallest loop or exception that contains MBB 77*e8d8bef9SDimitry Andric const SortRegion *getRegionFor(const MachineBasicBlock *MBB); 78*e8d8bef9SDimitry Andric 79*e8d8bef9SDimitry Andric // Return the "bottom" block among all blocks dominated by the region 80*e8d8bef9SDimitry Andric // (MachineLoop or WebAssemblyException) header. This works when the entity is 81*e8d8bef9SDimitry Andric // discontiguous. 82*e8d8bef9SDimitry Andric MachineBasicBlock *getBottom(const SortRegion *R); 83*e8d8bef9SDimitry Andric MachineBasicBlock *getBottom(const MachineLoop *ML); 84*e8d8bef9SDimitry Andric MachineBasicBlock *getBottom(const WebAssemblyException *WE); 85*e8d8bef9SDimitry Andric }; 86*e8d8bef9SDimitry Andric 87*e8d8bef9SDimitry Andric } // end namespace WebAssembly 88*e8d8bef9SDimitry Andric 89*e8d8bef9SDimitry Andric } // end namespace llvm 90*e8d8bef9SDimitry Andric 91*e8d8bef9SDimitry Andric #endif 92