//===- 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/Analysis/RegionInfo.h" #include "llvm/Analysis/RegionIterator.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" namespace llvm { class MachineDominatorTree; struct MachinePostDominatorTree; class MachineRegion; class MachineRegionNode; class MachineRegionInfo; template<> struct RegionTraits { typedef MachineFunction FuncT; typedef MachineBasicBlock BlockT; typedef MachineRegion RegionT; typedef MachineRegionNode RegionNodeT; typedef MachineRegionInfo RegionInfoT; typedef MachineDominatorTree DomTreeT; typedef MachineDomTreeNode DomTreeNodeT; typedef MachinePostDominatorTree PostDomTreeT; typedef MachineDominanceFrontier DomFrontierT; typedef MachineInstr InstT; typedef MachineLoop LoopT; typedef MachineLoopInfo LoopInfoT; 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) { } ~MachineRegionNode() { } 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(); virtual ~MachineRegionInfo(); // 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(); 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 > { typedef df_iterator, false, GraphTraits > > nodes_iterator; static NodeType *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 { typedef df_iterator, false, GraphTraits > > nodes_iterator; static NodeType *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_INSTANTIATION(class RegionBase>); EXTERN_TEMPLATE_INSTANTIATION(class RegionNodeBase>); EXTERN_TEMPLATE_INSTANTIATION(class RegionInfoBase>); } #endif