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