1//===- llvm/CodeGen/MachineRegionInfo.h -------------------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLVM_CODEGEN_MACHINEREGIONINFO_H
11#define LLVM_CODEGEN_MACHINEREGIONINFO_H
12
13#include "llvm/ADT/DepthFirstIterator.h"
14#include "llvm/Analysis/RegionInfo.h"
15#include "llvm/Analysis/RegionIterator.h"
16#include "llvm/CodeGen/MachineBasicBlock.h"
17#include "llvm/CodeGen/MachineDominanceFrontier.h"
18#include "llvm/CodeGen/MachineDominators.h"
19#include "llvm/CodeGen/MachineFunction.h"
20#include "llvm/CodeGen/MachineFunctionPass.h"
21#include "llvm/CodeGen/MachineLoopInfo.h"
22#include <cassert>
23
24namespace llvm {
25
26struct MachinePostDominatorTree;
27class MachineRegion;
28class MachineRegionNode;
29class MachineRegionInfo;
30
31template <> struct RegionTraits<MachineFunction> {
32  using FuncT = MachineFunction;
33  using BlockT = MachineBasicBlock;
34  using RegionT = MachineRegion;
35  using RegionNodeT = MachineRegionNode;
36  using RegionInfoT = MachineRegionInfo;
37  using DomTreeT = MachineDominatorTree;
38  using DomTreeNodeT = MachineDomTreeNode;
39  using PostDomTreeT = MachinePostDominatorTree;
40  using DomFrontierT = MachineDominanceFrontier;
41  using InstT = MachineInstr;
42  using LoopT = MachineLoop;
43  using LoopInfoT = MachineLoopInfo;
44
45  static unsigned getNumSuccessors(MachineBasicBlock *BB) {
46    return BB->succ_size();
47  }
48};
49
50class MachineRegionNode : public RegionNodeBase<RegionTraits<MachineFunction>> {
51public:
52  inline MachineRegionNode(MachineRegion *Parent, MachineBasicBlock *Entry,
53                           bool isSubRegion = false)
54      : RegionNodeBase<RegionTraits<MachineFunction>>(Parent, Entry,
55                                                      isSubRegion) {}
56
57  bool operator==(const MachineRegion &RN) const {
58    return this == reinterpret_cast<const MachineRegionNode *>(&RN);
59  }
60};
61
62class MachineRegion : public RegionBase<RegionTraits<MachineFunction>> {
63public:
64  MachineRegion(MachineBasicBlock *Entry, MachineBasicBlock *Exit,
65                MachineRegionInfo *RI, MachineDominatorTree *DT,
66                MachineRegion *Parent = nullptr);
67  ~MachineRegion();
68
69  bool operator==(const MachineRegionNode &RN) const {
70    return &RN == reinterpret_cast<const MachineRegionNode *>(this);
71  }
72};
73
74class MachineRegionInfo : public RegionInfoBase<RegionTraits<MachineFunction>> {
75public:
76  explicit MachineRegionInfo();
77  ~MachineRegionInfo() override;
78
79  // updateStatistics - Update statistic about created regions.
80  void updateStatistics(MachineRegion *R) final;
81
82  void recalculate(MachineFunction &F, MachineDominatorTree *DT,
83                   MachinePostDominatorTree *PDT, MachineDominanceFrontier *DF);
84};
85
86class MachineRegionInfoPass : public MachineFunctionPass {
87  MachineRegionInfo RI;
88
89public:
90  static char ID;
91
92  explicit MachineRegionInfoPass();
93  ~MachineRegionInfoPass() override;
94
95  MachineRegionInfo &getRegionInfo() { return RI; }
96
97  const MachineRegionInfo &getRegionInfo() const { return RI; }
98
99  /// @name MachineFunctionPass interface
100  //@{
101  bool runOnMachineFunction(MachineFunction &F) override;
102  void releaseMemory() override;
103  void verifyAnalysis() const override;
104  void getAnalysisUsage(AnalysisUsage &AU) const override;
105  void print(raw_ostream &OS, const Module *) const override;
106  void dump() const;
107  //@}
108};
109
110template <>
111template <>
112inline MachineBasicBlock *
113RegionNodeBase<RegionTraits<MachineFunction>>::getNodeAs<MachineBasicBlock>()
114    const {
115  assert(!isSubRegion() && "This is not a MachineBasicBlock RegionNode!");
116  return getEntry();
117}
118
119template <>
120template <>
121inline MachineRegion *
122RegionNodeBase<RegionTraits<MachineFunction>>::getNodeAs<MachineRegion>()
123    const {
124  assert(isSubRegion() && "This is not a subregion RegionNode!");
125  auto Unconst =
126      const_cast<RegionNodeBase<RegionTraits<MachineFunction>> *>(this);
127  return reinterpret_cast<MachineRegion *>(Unconst);
128}
129
130RegionNodeGraphTraits(MachineRegionNode, MachineBasicBlock, MachineRegion);
131RegionNodeGraphTraits(const MachineRegionNode, MachineBasicBlock,
132                      MachineRegion);
133
134RegionGraphTraits(MachineRegion, MachineRegionNode);
135RegionGraphTraits(const MachineRegion, const MachineRegionNode);
136
137template <>
138struct GraphTraits<MachineRegionInfo *>
139    : public GraphTraits<FlatIt<MachineRegionNode *>> {
140  using nodes_iterator = df_iterator<NodeRef, df_iterator_default_set<NodeRef>,
141                                     false, GraphTraits<FlatIt<NodeRef>>>;
142
143  static NodeRef getEntryNode(MachineRegionInfo *RI) {
144    return GraphTraits<FlatIt<MachineRegion *>>::getEntryNode(
145        RI->getTopLevelRegion());
146  }
147
148  static nodes_iterator nodes_begin(MachineRegionInfo *RI) {
149    return nodes_iterator::begin(getEntryNode(RI));
150  }
151
152  static nodes_iterator nodes_end(MachineRegionInfo *RI) {
153    return nodes_iterator::end(getEntryNode(RI));
154  }
155};
156
157template <>
158struct GraphTraits<MachineRegionInfoPass *>
159    : public GraphTraits<MachineRegionInfo *> {
160  using nodes_iterator = df_iterator<NodeRef, df_iterator_default_set<NodeRef>,
161                                     false, GraphTraits<FlatIt<NodeRef>>>;
162
163  static NodeRef getEntryNode(MachineRegionInfoPass *RI) {
164    return GraphTraits<MachineRegionInfo *>::getEntryNode(&RI->getRegionInfo());
165  }
166
167  static nodes_iterator nodes_begin(MachineRegionInfoPass *RI) {
168    return GraphTraits<MachineRegionInfo *>::nodes_begin(&RI->getRegionInfo());
169  }
170
171  static nodes_iterator nodes_end(MachineRegionInfoPass *RI) {
172    return GraphTraits<MachineRegionInfo *>::nodes_end(&RI->getRegionInfo());
173  }
174};
175
176extern template class RegionBase<RegionTraits<MachineFunction>>;
177extern template class RegionNodeBase<RegionTraits<MachineFunction>>;
178extern template class RegionInfoBase<RegionTraits<MachineFunction>>;
179
180} // end namespace llvm
181
182#endif // LLVM_CODEGEN_MACHINEREGIONINFO_H
183