10b57cec5SDimitry Andric //===- llvm/CodeGen/MachineRegionInfo.h -------------------------*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #ifndef LLVM_CODEGEN_MACHINEREGIONINFO_H 100b57cec5SDimitry Andric #define LLVM_CODEGEN_MACHINEREGIONINFO_H 110b57cec5SDimitry Andric 120b57cec5SDimitry Andric #include "llvm/ADT/DepthFirstIterator.h" 130b57cec5SDimitry Andric #include "llvm/Analysis/RegionInfo.h" 140b57cec5SDimitry Andric #include "llvm/Analysis/RegionIterator.h" 150b57cec5SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h" 160b57cec5SDimitry Andric #include "llvm/CodeGen/MachineDominanceFrontier.h" 170b57cec5SDimitry Andric #include "llvm/CodeGen/MachineDominators.h" 180b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h" 190b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunctionPass.h" 200b57cec5SDimitry Andric #include "llvm/CodeGen/MachineLoopInfo.h" 210b57cec5SDimitry Andric #include <cassert> 220b57cec5SDimitry Andric 230b57cec5SDimitry Andric namespace llvm { 240b57cec5SDimitry Andric 25*8bcb0991SDimitry Andric class MachinePostDominatorTree; 260b57cec5SDimitry Andric class MachineRegion; 270b57cec5SDimitry Andric class MachineRegionNode; 280b57cec5SDimitry Andric class MachineRegionInfo; 290b57cec5SDimitry Andric 300b57cec5SDimitry Andric template <> struct RegionTraits<MachineFunction> { 310b57cec5SDimitry Andric using FuncT = MachineFunction; 320b57cec5SDimitry Andric using BlockT = MachineBasicBlock; 330b57cec5SDimitry Andric using RegionT = MachineRegion; 340b57cec5SDimitry Andric using RegionNodeT = MachineRegionNode; 350b57cec5SDimitry Andric using RegionInfoT = MachineRegionInfo; 360b57cec5SDimitry Andric using DomTreeT = MachineDominatorTree; 370b57cec5SDimitry Andric using DomTreeNodeT = MachineDomTreeNode; 380b57cec5SDimitry Andric using PostDomTreeT = MachinePostDominatorTree; 390b57cec5SDimitry Andric using DomFrontierT = MachineDominanceFrontier; 400b57cec5SDimitry Andric using InstT = MachineInstr; 410b57cec5SDimitry Andric using LoopT = MachineLoop; 420b57cec5SDimitry Andric using LoopInfoT = MachineLoopInfo; 430b57cec5SDimitry Andric 440b57cec5SDimitry Andric static unsigned getNumSuccessors(MachineBasicBlock *BB) { 450b57cec5SDimitry Andric return BB->succ_size(); 460b57cec5SDimitry Andric } 470b57cec5SDimitry Andric }; 480b57cec5SDimitry Andric 490b57cec5SDimitry Andric class MachineRegionNode : public RegionNodeBase<RegionTraits<MachineFunction>> { 500b57cec5SDimitry Andric public: 510b57cec5SDimitry Andric inline MachineRegionNode(MachineRegion *Parent, MachineBasicBlock *Entry, 520b57cec5SDimitry Andric bool isSubRegion = false) 530b57cec5SDimitry Andric : RegionNodeBase<RegionTraits<MachineFunction>>(Parent, Entry, 540b57cec5SDimitry Andric isSubRegion) {} 550b57cec5SDimitry Andric 560b57cec5SDimitry Andric bool operator==(const MachineRegion &RN) const { 570b57cec5SDimitry Andric return this == reinterpret_cast<const MachineRegionNode *>(&RN); 580b57cec5SDimitry Andric } 590b57cec5SDimitry Andric }; 600b57cec5SDimitry Andric 610b57cec5SDimitry Andric class MachineRegion : public RegionBase<RegionTraits<MachineFunction>> { 620b57cec5SDimitry Andric public: 630b57cec5SDimitry Andric MachineRegion(MachineBasicBlock *Entry, MachineBasicBlock *Exit, 640b57cec5SDimitry Andric MachineRegionInfo *RI, MachineDominatorTree *DT, 650b57cec5SDimitry Andric MachineRegion *Parent = nullptr); 660b57cec5SDimitry Andric ~MachineRegion(); 670b57cec5SDimitry Andric 680b57cec5SDimitry Andric bool operator==(const MachineRegionNode &RN) const { 690b57cec5SDimitry Andric return &RN == reinterpret_cast<const MachineRegionNode *>(this); 700b57cec5SDimitry Andric } 710b57cec5SDimitry Andric }; 720b57cec5SDimitry Andric 730b57cec5SDimitry Andric class MachineRegionInfo : public RegionInfoBase<RegionTraits<MachineFunction>> { 740b57cec5SDimitry Andric public: 750b57cec5SDimitry Andric explicit MachineRegionInfo(); 760b57cec5SDimitry Andric ~MachineRegionInfo() override; 770b57cec5SDimitry Andric 780b57cec5SDimitry Andric // updateStatistics - Update statistic about created regions. 790b57cec5SDimitry Andric void updateStatistics(MachineRegion *R) final; 800b57cec5SDimitry Andric 810b57cec5SDimitry Andric void recalculate(MachineFunction &F, MachineDominatorTree *DT, 820b57cec5SDimitry Andric MachinePostDominatorTree *PDT, MachineDominanceFrontier *DF); 830b57cec5SDimitry Andric }; 840b57cec5SDimitry Andric 850b57cec5SDimitry Andric class MachineRegionInfoPass : public MachineFunctionPass { 860b57cec5SDimitry Andric MachineRegionInfo RI; 870b57cec5SDimitry Andric 880b57cec5SDimitry Andric public: 890b57cec5SDimitry Andric static char ID; 900b57cec5SDimitry Andric 910b57cec5SDimitry Andric explicit MachineRegionInfoPass(); 920b57cec5SDimitry Andric ~MachineRegionInfoPass() override; 930b57cec5SDimitry Andric 940b57cec5SDimitry Andric MachineRegionInfo &getRegionInfo() { return RI; } 950b57cec5SDimitry Andric 960b57cec5SDimitry Andric const MachineRegionInfo &getRegionInfo() const { return RI; } 970b57cec5SDimitry Andric 980b57cec5SDimitry Andric /// @name MachineFunctionPass interface 990b57cec5SDimitry Andric //@{ 1000b57cec5SDimitry Andric bool runOnMachineFunction(MachineFunction &F) override; 1010b57cec5SDimitry Andric void releaseMemory() override; 1020b57cec5SDimitry Andric void verifyAnalysis() const override; 1030b57cec5SDimitry Andric void getAnalysisUsage(AnalysisUsage &AU) const override; 1040b57cec5SDimitry Andric void print(raw_ostream &OS, const Module *) const override; 1050b57cec5SDimitry Andric void dump() const; 1060b57cec5SDimitry Andric //@} 1070b57cec5SDimitry Andric }; 1080b57cec5SDimitry Andric 1090b57cec5SDimitry Andric template <> 1100b57cec5SDimitry Andric template <> 1110b57cec5SDimitry Andric inline MachineBasicBlock * 1120b57cec5SDimitry Andric RegionNodeBase<RegionTraits<MachineFunction>>::getNodeAs<MachineBasicBlock>() 1130b57cec5SDimitry Andric const { 1140b57cec5SDimitry Andric assert(!isSubRegion() && "This is not a MachineBasicBlock RegionNode!"); 1150b57cec5SDimitry Andric return getEntry(); 1160b57cec5SDimitry Andric } 1170b57cec5SDimitry Andric 1180b57cec5SDimitry Andric template <> 1190b57cec5SDimitry Andric template <> 1200b57cec5SDimitry Andric inline MachineRegion * 1210b57cec5SDimitry Andric RegionNodeBase<RegionTraits<MachineFunction>>::getNodeAs<MachineRegion>() 1220b57cec5SDimitry Andric const { 1230b57cec5SDimitry Andric assert(isSubRegion() && "This is not a subregion RegionNode!"); 1240b57cec5SDimitry Andric auto Unconst = 1250b57cec5SDimitry Andric const_cast<RegionNodeBase<RegionTraits<MachineFunction>> *>(this); 1260b57cec5SDimitry Andric return reinterpret_cast<MachineRegion *>(Unconst); 1270b57cec5SDimitry Andric } 1280b57cec5SDimitry Andric 1290b57cec5SDimitry Andric RegionNodeGraphTraits(MachineRegionNode, MachineBasicBlock, MachineRegion); 1300b57cec5SDimitry Andric RegionNodeGraphTraits(const MachineRegionNode, MachineBasicBlock, 1310b57cec5SDimitry Andric MachineRegion); 1320b57cec5SDimitry Andric 1330b57cec5SDimitry Andric RegionGraphTraits(MachineRegion, MachineRegionNode); 1340b57cec5SDimitry Andric RegionGraphTraits(const MachineRegion, const MachineRegionNode); 1350b57cec5SDimitry Andric 1360b57cec5SDimitry Andric template <> 1370b57cec5SDimitry Andric struct GraphTraits<MachineRegionInfo *> 1380b57cec5SDimitry Andric : public GraphTraits<FlatIt<MachineRegionNode *>> { 1390b57cec5SDimitry Andric using nodes_iterator = df_iterator<NodeRef, df_iterator_default_set<NodeRef>, 1400b57cec5SDimitry Andric false, GraphTraits<FlatIt<NodeRef>>>; 1410b57cec5SDimitry Andric 1420b57cec5SDimitry Andric static NodeRef getEntryNode(MachineRegionInfo *RI) { 1430b57cec5SDimitry Andric return GraphTraits<FlatIt<MachineRegion *>>::getEntryNode( 1440b57cec5SDimitry Andric RI->getTopLevelRegion()); 1450b57cec5SDimitry Andric } 1460b57cec5SDimitry Andric 1470b57cec5SDimitry Andric static nodes_iterator nodes_begin(MachineRegionInfo *RI) { 1480b57cec5SDimitry Andric return nodes_iterator::begin(getEntryNode(RI)); 1490b57cec5SDimitry Andric } 1500b57cec5SDimitry Andric 1510b57cec5SDimitry Andric static nodes_iterator nodes_end(MachineRegionInfo *RI) { 1520b57cec5SDimitry Andric return nodes_iterator::end(getEntryNode(RI)); 1530b57cec5SDimitry Andric } 1540b57cec5SDimitry Andric }; 1550b57cec5SDimitry Andric 1560b57cec5SDimitry Andric template <> 1570b57cec5SDimitry Andric struct GraphTraits<MachineRegionInfoPass *> 1580b57cec5SDimitry Andric : public GraphTraits<MachineRegionInfo *> { 1590b57cec5SDimitry Andric using nodes_iterator = df_iterator<NodeRef, df_iterator_default_set<NodeRef>, 1600b57cec5SDimitry Andric false, GraphTraits<FlatIt<NodeRef>>>; 1610b57cec5SDimitry Andric 1620b57cec5SDimitry Andric static NodeRef getEntryNode(MachineRegionInfoPass *RI) { 1630b57cec5SDimitry Andric return GraphTraits<MachineRegionInfo *>::getEntryNode(&RI->getRegionInfo()); 1640b57cec5SDimitry Andric } 1650b57cec5SDimitry Andric 1660b57cec5SDimitry Andric static nodes_iterator nodes_begin(MachineRegionInfoPass *RI) { 1670b57cec5SDimitry Andric return GraphTraits<MachineRegionInfo *>::nodes_begin(&RI->getRegionInfo()); 1680b57cec5SDimitry Andric } 1690b57cec5SDimitry Andric 1700b57cec5SDimitry Andric static nodes_iterator nodes_end(MachineRegionInfoPass *RI) { 1710b57cec5SDimitry Andric return GraphTraits<MachineRegionInfo *>::nodes_end(&RI->getRegionInfo()); 1720b57cec5SDimitry Andric } 1730b57cec5SDimitry Andric }; 1740b57cec5SDimitry Andric 1750b57cec5SDimitry Andric extern template class RegionBase<RegionTraits<MachineFunction>>; 1760b57cec5SDimitry Andric extern template class RegionNodeBase<RegionTraits<MachineFunction>>; 1770b57cec5SDimitry Andric extern template class RegionInfoBase<RegionTraits<MachineFunction>>; 1780b57cec5SDimitry Andric 1790b57cec5SDimitry Andric } // end namespace llvm 1800b57cec5SDimitry Andric 1810b57cec5SDimitry Andric #endif // LLVM_CODEGEN_MACHINEREGIONINFO_H 182