xref: /freebsd/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineRegionInfo.h (revision 5b27928474e6a4103d65b347544705c40c9618fd)
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