//===- llvm/CodeGen/MachineRegionInfo.h -------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #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 "llvm/CodeGen/MachinePassManager.h" #include namespace llvm { class 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: LLVM_ABI MachineRegion(MachineBasicBlock *Entry, MachineBasicBlock *Exit, MachineRegionInfo *RI, MachineDominatorTree *DT, MachineRegion *Parent = nullptr); LLVM_ABI ~MachineRegion(); bool operator==(const MachineRegionNode &RN) const { return &RN == reinterpret_cast(this); } }; class LLVM_ABI MachineRegionInfo : public RegionInfoBase> { public: using Base = RegionInfoBase>; explicit MachineRegionInfo(); ~MachineRegionInfo() override; MachineRegionInfo(MachineRegionInfo &&Arg) : Base(std::move(static_cast(Arg))) { updateRegionTree(*this, TopLevelRegion); } MachineRegionInfo &operator=(MachineRegionInfo &&RHS) { Base::operator=(std::move(static_cast(RHS))); updateRegionTree(*this, TopLevelRegion); return *this; } /// Handle invalidation explicitly. bool invalidate(MachineFunction &F, const PreservedAnalyses &PA, MachineFunctionAnalysisManager::Invalidator &); // updateStatistics - Update statistic about created regions. void updateStatistics(MachineRegion *R) final; void recalculate(MachineFunction &F, MachineDominatorTree *DT, MachinePostDominatorTree *PDT, MachineDominanceFrontier *DF); }; class LLVM_ABI MachineRegionInfoAnalysis : public AnalysisInfoMixin { friend AnalysisInfoMixin; static AnalysisKey Key; public: using Result = MachineRegionInfo; Result run(MachineFunction &F, MachineFunctionAnalysisManager &AM); }; class LLVM_ABI MachineRegionInfoPrinterPass : public RequiredPassInfoMixin { raw_ostream &OS; public: explicit MachineRegionInfoPrinterPass(raw_ostream &OS) : OS(OS) {} PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM); }; class LLVM_ABI 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