//===- llvm/CodeGen/MachineRegionInfo.h -------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #ifndef LLVM_CODEGEN_MACHINEREGIONINFO_H #define LLVM_CODEGEN_MACHINEREGIONINFO_H #include "llvm/ADT/DepthFirstIterator.h" #include "llvm/Analysis/RegionInfo.h" #include "llvm/Analysis/RegionIterator.h" #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineDominanceFrontier.h" #include "llvm/CodeGen/MachineDominators.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineLoopInfo.h" #include namespace llvm { struct MachinePostDominatorTree; class MachineRegion; class MachineRegionNode; class MachineRegionInfo; template <> struct RegionTraits { using FuncT = MachineFunction; using BlockT = MachineBasicBlock; using RegionT = MachineRegion; using RegionNodeT = MachineRegionNode; using RegionInfoT = MachineRegionInfo; using DomTreeT = MachineDominatorTree; using DomTreeNodeT = MachineDomTreeNode; using PostDomTreeT = MachinePostDominatorTree; using DomFrontierT = MachineDominanceFrontier; using InstT = MachineInstr; using LoopT = MachineLoop; using LoopInfoT = MachineLoopInfo; static unsigned getNumSuccessors(MachineBasicBlock *BB) { return BB->succ_size(); } }; class MachineRegionNode : public RegionNodeBase> { public: inline MachineRegionNode(MachineRegion *Parent, MachineBasicBlock *Entry, bool isSubRegion = false) : RegionNodeBase>(Parent, Entry, isSubRegion) {} bool operator==(const MachineRegion &RN) const { return this == reinterpret_cast(&RN); } }; class MachineRegion : public RegionBase> { public: MachineRegion(MachineBasicBlock *Entry, MachineBasicBlock *Exit, MachineRegionInfo *RI, MachineDominatorTree *DT, MachineRegion *Parent = nullptr); ~MachineRegion(); bool operator==(const MachineRegionNode &RN) const { return &RN == reinterpret_cast(this); } }; class MachineRegionInfo : public RegionInfoBase> { public: explicit MachineRegionInfo(); ~MachineRegionInfo() override; // updateStatistics - Update statistic about created regions. void updateStatistics(MachineRegion *R) final; void recalculate(MachineFunction &F, MachineDominatorTree *DT, MachinePostDominatorTree *PDT, MachineDominanceFrontier *DF); }; class MachineRegionInfoPass : public MachineFunctionPass { MachineRegionInfo RI; public: static char ID; explicit MachineRegionInfoPass(); ~MachineRegionInfoPass() override; MachineRegionInfo &getRegionInfo() { return RI; } const MachineRegionInfo &getRegionInfo() const { return RI; } /// @name MachineFunctionPass interface //@{ bool runOnMachineFunction(MachineFunction &F) override; void releaseMemory() override; void verifyAnalysis() const override; void getAnalysisUsage(AnalysisUsage &AU) const override; void print(raw_ostream &OS, const Module *) const override; void dump() const; //@} }; template <> template <> inline MachineBasicBlock * RegionNodeBase>::getNodeAs() const { assert(!isSubRegion() && "This is not a MachineBasicBlock RegionNode!"); return getEntry(); } template <> template <> inline MachineRegion * RegionNodeBase>::getNodeAs() const { assert(isSubRegion() && "This is not a subregion RegionNode!"); auto Unconst = const_cast> *>(this); return reinterpret_cast(Unconst); } RegionNodeGraphTraits(MachineRegionNode, MachineBasicBlock, MachineRegion); RegionNodeGraphTraits(const MachineRegionNode, MachineBasicBlock, MachineRegion); RegionGraphTraits(MachineRegion, MachineRegionNode); RegionGraphTraits(const MachineRegion, const MachineRegionNode); template <> struct GraphTraits : public GraphTraits> { using nodes_iterator = df_iterator, false, GraphTraits>>; static NodeRef getEntryNode(MachineRegionInfo *RI) { return GraphTraits>::getEntryNode( RI->getTopLevelRegion()); } static nodes_iterator nodes_begin(MachineRegionInfo *RI) { return nodes_iterator::begin(getEntryNode(RI)); } static nodes_iterator nodes_end(MachineRegionInfo *RI) { return nodes_iterator::end(getEntryNode(RI)); } }; template <> struct GraphTraits : public GraphTraits { using nodes_iterator = df_iterator, false, GraphTraits>>; static NodeRef getEntryNode(MachineRegionInfoPass *RI) { return GraphTraits::getEntryNode(&RI->getRegionInfo()); } static nodes_iterator nodes_begin(MachineRegionInfoPass *RI) { return GraphTraits::nodes_begin(&RI->getRegionInfo()); } static nodes_iterator nodes_end(MachineRegionInfoPass *RI) { return GraphTraits::nodes_end(&RI->getRegionInfo()); } }; extern template class RegionBase>; extern template class RegionNodeBase>; extern template class RegionInfoBase>; } // end namespace llvm #endif // LLVM_CODEGEN_MACHINEREGIONINFO_H