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