| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,183 @@ | ||
| //===- 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<MachineFunction> { | ||
| 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<RegionTraits<MachineFunction>> { | ||
| public: | ||
| inline MachineRegionNode(MachineRegion *Parent, | ||
| MachineBasicBlock *Entry, | ||
| bool isSubRegion = false) | ||
| : RegionNodeBase<RegionTraits<MachineFunction>>(Parent, Entry, isSubRegion) { | ||
|
|
||
| } | ||
|
|
||
| ~MachineRegionNode() { } | ||
|
|
||
| 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(); | ||
|
|
||
| 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<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*> > { | ||
| typedef df_iterator<NodeType*, SmallPtrSet<NodeType*, 8>, false, | ||
| GraphTraits<FlatIt<NodeType*> > > nodes_iterator; | ||
|
|
||
| static NodeType *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 *> { | ||
| typedef df_iterator<NodeType*, SmallPtrSet<NodeType*, 8>, false, | ||
| GraphTraits<FlatIt<NodeType*> > > nodes_iterator; | ||
|
|
||
| static NodeType *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_INSTANTIATION(class RegionBase<RegionTraits<MachineFunction>>); | ||
| EXTERN_TEMPLATE_INSTANTIATION(class RegionNodeBase<RegionTraits<MachineFunction>>); | ||
| EXTERN_TEMPLATE_INSTANTIATION(class RegionInfoBase<RegionTraits<MachineFunction>>); | ||
|
|
||
| } | ||
|
|
||
| #endif |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,137 @@ | ||
|
|
||
| #include "llvm/CodeGen/MachineRegionInfo.h" | ||
| #include "llvm/CodeGen/MachinePostDominators.h" | ||
| #include "llvm/ADT/Statistic.h" | ||
| #include "llvm/Analysis/RegionInfoImpl.h" | ||
|
|
||
| using namespace llvm; | ||
|
|
||
| STATISTIC(numMachineRegions, "The # of machine regions"); | ||
| STATISTIC(numMachineSimpleRegions, "The # of simple machine regions"); | ||
|
|
||
| namespace llvm { | ||
| template class RegionBase<RegionTraits<MachineFunction>>; | ||
| template class RegionNodeBase<RegionTraits<MachineFunction>>; | ||
| template class RegionInfoBase<RegionTraits<MachineFunction>>; | ||
| } | ||
|
|
||
| //===----------------------------------------------------------------------===// | ||
| // MachineRegion implementation | ||
| // | ||
|
|
||
| MachineRegion::MachineRegion(MachineBasicBlock *Entry, MachineBasicBlock *Exit, | ||
| MachineRegionInfo* RI, | ||
| MachineDominatorTree *DT, MachineRegion *Parent) : | ||
| RegionBase<RegionTraits<MachineFunction>>(Entry, Exit, RI, DT, Parent) { | ||
|
|
||
| } | ||
|
|
||
| MachineRegion::~MachineRegion() { } | ||
|
|
||
| //===----------------------------------------------------------------------===// | ||
| // MachineRegionInfo implementation | ||
| // | ||
|
|
||
| MachineRegionInfo::MachineRegionInfo() : | ||
| RegionInfoBase<RegionTraits<MachineFunction>>() { | ||
|
|
||
| } | ||
|
|
||
| MachineRegionInfo::~MachineRegionInfo() { | ||
|
|
||
| } | ||
|
|
||
| void MachineRegionInfo::updateStatistics(MachineRegion *R) { | ||
| ++numMachineRegions; | ||
|
|
||
| // TODO: Slow. Should only be enabled if -stats is used. | ||
| if (R->isSimple()) | ||
| ++numMachineSimpleRegions; | ||
| } | ||
|
|
||
| void MachineRegionInfo::MachineRegionInfo::recalculate( | ||
| MachineFunction &F, | ||
| MachineDominatorTree *DT_, | ||
| MachinePostDominatorTree *PDT_, | ||
| MachineDominanceFrontier *DF_) { | ||
| DT = DT_; | ||
| PDT = PDT_; | ||
| DF = DF_; | ||
|
|
||
| MachineBasicBlock *Entry = GraphTraits<MachineFunction*>::getEntryNode(&F); | ||
|
|
||
| TopLevelRegion = new MachineRegion(Entry, nullptr, this, DT, nullptr); | ||
| updateStatistics(TopLevelRegion); | ||
| calculate(F); | ||
| } | ||
|
|
||
| //===----------------------------------------------------------------------===// | ||
| // MachineRegionInfoPass implementation | ||
| // | ||
|
|
||
| MachineRegionInfoPass::MachineRegionInfoPass() : MachineFunctionPass(ID) { | ||
| initializeMachineRegionInfoPassPass(*PassRegistry::getPassRegistry()); | ||
| } | ||
|
|
||
| MachineRegionInfoPass::~MachineRegionInfoPass() { | ||
|
|
||
| } | ||
|
|
||
| bool MachineRegionInfoPass::runOnMachineFunction(MachineFunction &F) { | ||
| releaseMemory(); | ||
|
|
||
| auto DT = &getAnalysis<MachineDominatorTree>(); | ||
| auto PDT = &getAnalysis<MachinePostDominatorTree>(); | ||
| auto DF = &getAnalysis<MachineDominanceFrontier>(); | ||
|
|
||
| RI.recalculate(F, DT, PDT, DF); | ||
| return false; | ||
| } | ||
|
|
||
| void MachineRegionInfoPass::releaseMemory() { | ||
| RI.releaseMemory(); | ||
| } | ||
|
|
||
| void MachineRegionInfoPass::verifyAnalysis() const { | ||
| // Only do verification when user wants to, otherwise this expensive check | ||
| // will be invoked by PMDataManager::verifyPreservedAnalysis when | ||
| // a regionpass (marked PreservedAll) finish. | ||
| if (MachineRegionInfo::VerifyRegionInfo) | ||
| RI.verifyAnalysis(); | ||
| } | ||
|
|
||
| void MachineRegionInfoPass::getAnalysisUsage(AnalysisUsage &AU) const { | ||
| AU.setPreservesAll(); | ||
| AU.addRequiredTransitive<DominatorTreeWrapperPass>(); | ||
| AU.addRequired<PostDominatorTree>(); | ||
| AU.addRequired<DominanceFrontier>(); | ||
| } | ||
|
|
||
| void MachineRegionInfoPass::print(raw_ostream &OS, const Module *) const { | ||
| RI.print(OS); | ||
| } | ||
|
|
||
| void MachineRegionInfoPass::dump() const { | ||
| RI.dump(); | ||
| } | ||
|
|
||
| char MachineRegionInfoPass::ID = 0; | ||
|
|
||
| INITIALIZE_PASS_BEGIN(MachineRegionInfoPass, "regions", | ||
| "Detect single entry single exit regions", true, true) | ||
| INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree) | ||
| INITIALIZE_PASS_DEPENDENCY(MachinePostDominatorTree) | ||
| INITIALIZE_PASS_DEPENDENCY(MachineDominanceFrontier) | ||
| INITIALIZE_PASS_END(MachineRegionInfoPass, "regions", | ||
| "Detect single entry single exit regions", true, true) | ||
|
|
||
| // Create methods available outside of this file, to use them | ||
| // "include/llvm/LinkAllPasses.h". Otherwise the pass would be deleted by | ||
| // the link time optimization. | ||
|
|
||
| namespace llvm { | ||
| FunctionPass *createMachineRegionInfoPass() { | ||
| return new MachineRegionInfoPass(); | ||
| } | ||
| } | ||
|
|