| //===- 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 <cassert> | |
| namespace llvm { | |
| class MachinePostDominatorTree; | |
| class MachineRegion; | |
| class MachineRegionNode; | |
| class MachineRegionInfo; | |
| template <> struct RegionTraits<MachineFunction> { | |
| 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<RegionTraits<MachineFunction>> { | |
| public: | |
| inline MachineRegionNode(MachineRegion *Parent, MachineBasicBlock *Entry, | |
| bool isSubRegion = false) | |
| : RegionNodeBase<RegionTraits<MachineFunction>>(Parent, Entry, | |
| isSubRegion) {} | |
| bool operator==(const MachineRegion &RN) const { | |
| return this == reinterpret_cast<const MachineRegionNode *>(&RN); | |
| } | |
| }; | |
| class MachineRegion : public RegionBase<RegionTraits<MachineFunction>> { | |
| public: | |
| MachineRegion(MachineBasicBlock *Entry, MachineBasicBlock *Exit, | |
| MachineRegionInfo *RI, MachineDominatorTree *DT, | |
| MachineRegion *Parent = nullptr); | |
| ~MachineRegion(); | |
| bool operator==(const MachineRegionNode &RN) const { | |
| return &RN == reinterpret_cast<const MachineRegionNode *>(this); | |
| } | |
| }; | |
| class MachineRegionInfo : public RegionInfoBase<RegionTraits<MachineFunction>> { | |
| 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<RegionTraits<MachineFunction>>::getNodeAs<MachineBasicBlock>() | |
| const { | |
| assert(!isSubRegion() && "This is not a MachineBasicBlock RegionNode!"); | |
| return getEntry(); | |
| } | |
| template <> | |
| template <> | |
| inline MachineRegion * | |
| RegionNodeBase<RegionTraits<MachineFunction>>::getNodeAs<MachineRegion>() | |
| const { | |
| assert(isSubRegion() && "This is not a subregion RegionNode!"); | |
| auto Unconst = | |
| const_cast<RegionNodeBase<RegionTraits<MachineFunction>> *>(this); | |
| return reinterpret_cast<MachineRegion *>(Unconst); | |
| } | |
| RegionNodeGraphTraits(MachineRegionNode, MachineBasicBlock, MachineRegion); | |
| RegionNodeGraphTraits(const MachineRegionNode, MachineBasicBlock, | |
| MachineRegion); | |
| RegionGraphTraits(MachineRegion, MachineRegionNode); | |
| RegionGraphTraits(const MachineRegion, const MachineRegionNode); | |
| template <> | |
| struct GraphTraits<MachineRegionInfo *> | |
| : public GraphTraits<FlatIt<MachineRegionNode *>> { | |
| using nodes_iterator = df_iterator<NodeRef, df_iterator_default_set<NodeRef>, | |
| false, GraphTraits<FlatIt<NodeRef>>>; | |
| static NodeRef getEntryNode(MachineRegionInfo *RI) { | |
| return GraphTraits<FlatIt<MachineRegion *>>::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<MachineRegionInfoPass *> | |
| : public GraphTraits<MachineRegionInfo *> { | |
| using nodes_iterator = df_iterator<NodeRef, df_iterator_default_set<NodeRef>, | |
| false, GraphTraits<FlatIt<NodeRef>>>; | |
| static NodeRef getEntryNode(MachineRegionInfoPass *RI) { | |
| return GraphTraits<MachineRegionInfo *>::getEntryNode(&RI->getRegionInfo()); | |
| } | |
| static nodes_iterator nodes_begin(MachineRegionInfoPass *RI) { | |
| return GraphTraits<MachineRegionInfo *>::nodes_begin(&RI->getRegionInfo()); | |
| } | |
| static nodes_iterator nodes_end(MachineRegionInfoPass *RI) { | |
| return GraphTraits<MachineRegionInfo *>::nodes_end(&RI->getRegionInfo()); | |
| } | |
| }; | |
| extern template class RegionBase<RegionTraits<MachineFunction>>; | |
| extern template class RegionNodeBase<RegionTraits<MachineFunction>>; | |
| extern template class RegionInfoBase<RegionTraits<MachineFunction>>; | |
| } // end namespace llvm | |
| #endif // LLVM_CODEGEN_MACHINEREGIONINFO_H |