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