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