16d97bb29SDimitry Andric //===- lib/Codegen/MachineRegionInfo.cpp ----------------------------------===//
26d97bb29SDimitry Andric //
36d97bb29SDimitry Andric //                     The LLVM Compiler Infrastructure
46d97bb29SDimitry Andric //
56d97bb29SDimitry Andric // This file is distributed under the University of Illinois Open Source
66d97bb29SDimitry Andric // License. See LICENSE.TXT for details.
76d97bb29SDimitry Andric //
86d97bb29SDimitry Andric //===----------------------------------------------------------------------===//
96d97bb29SDimitry Andric 
10db17bf38SDimitry Andric #include "llvm/CodeGen/MachineRegionInfo.h"
1191bc56edSDimitry Andric #include "llvm/ADT/Statistic.h"
1291bc56edSDimitry Andric #include "llvm/Analysis/RegionInfoImpl.h"
1339d628a0SDimitry Andric #include "llvm/CodeGen/MachinePostDominators.h"
14*4ba319b5SDimitry Andric #include "llvm/Config/llvm-config.h"
156d97bb29SDimitry Andric #include "llvm/Pass.h"
166d97bb29SDimitry Andric #include "llvm/Support/Compiler.h"
176d97bb29SDimitry Andric #include "llvm/Support/Debug.h"
1839d628a0SDimitry Andric 
197a7e6055SDimitry Andric #define DEBUG_TYPE "machine-region-info"
2091bc56edSDimitry Andric 
2191bc56edSDimitry Andric using namespace llvm;
2291bc56edSDimitry Andric 
2391bc56edSDimitry Andric STATISTIC(numMachineRegions,       "The # of machine regions");
2491bc56edSDimitry Andric STATISTIC(numMachineSimpleRegions, "The # of simple machine regions");
2591bc56edSDimitry Andric 
2691bc56edSDimitry Andric namespace llvm {
276d97bb29SDimitry Andric 
2891bc56edSDimitry Andric template class RegionBase<RegionTraits<MachineFunction>>;
2991bc56edSDimitry Andric template class RegionNodeBase<RegionTraits<MachineFunction>>;
3091bc56edSDimitry Andric template class RegionInfoBase<RegionTraits<MachineFunction>>;
316d97bb29SDimitry Andric 
326d97bb29SDimitry Andric } // end namespace llvm
3391bc56edSDimitry Andric 
3491bc56edSDimitry Andric //===----------------------------------------------------------------------===//
3591bc56edSDimitry Andric // MachineRegion implementation
3691bc56edSDimitry Andric 
MachineRegion(MachineBasicBlock * Entry,MachineBasicBlock * Exit,MachineRegionInfo * RI,MachineDominatorTree * DT,MachineRegion * Parent)3791bc56edSDimitry Andric MachineRegion::MachineRegion(MachineBasicBlock *Entry, MachineBasicBlock *Exit,
3891bc56edSDimitry Andric                              MachineRegionInfo* RI,
3991bc56edSDimitry Andric                              MachineDominatorTree *DT, MachineRegion *Parent) :
406d97bb29SDimitry Andric   RegionBase<RegionTraits<MachineFunction>>(Entry, Exit, RI, DT, Parent) {}
4191bc56edSDimitry Andric 
426d97bb29SDimitry Andric MachineRegion::~MachineRegion() = default;
4391bc56edSDimitry Andric 
4491bc56edSDimitry Andric //===----------------------------------------------------------------------===//
4591bc56edSDimitry Andric // MachineRegionInfo implementation
4691bc56edSDimitry Andric 
476d97bb29SDimitry Andric MachineRegionInfo::MachineRegionInfo() = default;
4891bc56edSDimitry Andric 
496d97bb29SDimitry Andric MachineRegionInfo::~MachineRegionInfo() = default;
5091bc56edSDimitry Andric 
updateStatistics(MachineRegion * R)5191bc56edSDimitry Andric void MachineRegionInfo::updateStatistics(MachineRegion *R) {
5291bc56edSDimitry Andric   ++numMachineRegions;
5391bc56edSDimitry Andric 
5491bc56edSDimitry Andric   // TODO: Slow. Should only be enabled if -stats is used.
5591bc56edSDimitry Andric   if (R->isSimple())
5691bc56edSDimitry Andric     ++numMachineSimpleRegions;
5791bc56edSDimitry Andric }
5891bc56edSDimitry Andric 
recalculate(MachineFunction & F,MachineDominatorTree * DT_,MachinePostDominatorTree * PDT_,MachineDominanceFrontier * DF_)5991bc56edSDimitry Andric void MachineRegionInfo::recalculate(MachineFunction &F,
6091bc56edSDimitry Andric                                     MachineDominatorTree *DT_,
6191bc56edSDimitry Andric                                     MachinePostDominatorTree *PDT_,
6291bc56edSDimitry Andric                                     MachineDominanceFrontier *DF_) {
6391bc56edSDimitry Andric   DT = DT_;
6491bc56edSDimitry Andric   PDT = PDT_;
6591bc56edSDimitry Andric   DF = DF_;
6691bc56edSDimitry Andric 
6791bc56edSDimitry Andric   MachineBasicBlock *Entry = GraphTraits<MachineFunction*>::getEntryNode(&F);
6891bc56edSDimitry Andric 
6991bc56edSDimitry Andric   TopLevelRegion = new MachineRegion(Entry, nullptr, this, DT, nullptr);
7091bc56edSDimitry Andric   updateStatistics(TopLevelRegion);
7191bc56edSDimitry Andric   calculate(F);
7291bc56edSDimitry Andric }
7391bc56edSDimitry Andric 
7491bc56edSDimitry Andric //===----------------------------------------------------------------------===//
7591bc56edSDimitry Andric // MachineRegionInfoPass implementation
7691bc56edSDimitry Andric //
7791bc56edSDimitry Andric 
MachineRegionInfoPass()7891bc56edSDimitry Andric MachineRegionInfoPass::MachineRegionInfoPass() : MachineFunctionPass(ID) {
7991bc56edSDimitry Andric   initializeMachineRegionInfoPassPass(*PassRegistry::getPassRegistry());
8091bc56edSDimitry Andric }
8191bc56edSDimitry Andric 
826d97bb29SDimitry Andric MachineRegionInfoPass::~MachineRegionInfoPass() = default;
8391bc56edSDimitry Andric 
runOnMachineFunction(MachineFunction & F)8491bc56edSDimitry Andric bool MachineRegionInfoPass::runOnMachineFunction(MachineFunction &F) {
8591bc56edSDimitry Andric   releaseMemory();
8691bc56edSDimitry Andric 
8791bc56edSDimitry Andric   auto DT = &getAnalysis<MachineDominatorTree>();
8891bc56edSDimitry Andric   auto PDT = &getAnalysis<MachinePostDominatorTree>();
8991bc56edSDimitry Andric   auto DF = &getAnalysis<MachineDominanceFrontier>();
9091bc56edSDimitry Andric 
9191bc56edSDimitry Andric   RI.recalculate(F, DT, PDT, DF);
927a7e6055SDimitry Andric 
93*4ba319b5SDimitry Andric   LLVM_DEBUG(RI.dump());
947a7e6055SDimitry Andric 
9591bc56edSDimitry Andric   return false;
9691bc56edSDimitry Andric }
9791bc56edSDimitry Andric 
releaseMemory()9891bc56edSDimitry Andric void MachineRegionInfoPass::releaseMemory() {
9991bc56edSDimitry Andric   RI.releaseMemory();
10091bc56edSDimitry Andric }
10191bc56edSDimitry Andric 
verifyAnalysis() const10291bc56edSDimitry Andric void MachineRegionInfoPass::verifyAnalysis() const {
10391bc56edSDimitry Andric   // Only do verification when user wants to, otherwise this expensive check
10491bc56edSDimitry Andric   // will be invoked by PMDataManager::verifyPreservedAnalysis when
10591bc56edSDimitry Andric   // a regionpass (marked PreservedAll) finish.
10691bc56edSDimitry Andric   if (MachineRegionInfo::VerifyRegionInfo)
10791bc56edSDimitry Andric     RI.verifyAnalysis();
10891bc56edSDimitry Andric }
10991bc56edSDimitry Andric 
getAnalysisUsage(AnalysisUsage & AU) const11091bc56edSDimitry Andric void MachineRegionInfoPass::getAnalysisUsage(AnalysisUsage &AU) const {
11191bc56edSDimitry Andric   AU.setPreservesAll();
1127a7e6055SDimitry Andric   AU.addRequired<MachineDominatorTree>();
1137a7e6055SDimitry Andric   AU.addRequired<MachinePostDominatorTree>();
1147a7e6055SDimitry Andric   AU.addRequired<MachineDominanceFrontier>();
1157a7e6055SDimitry Andric   MachineFunctionPass::getAnalysisUsage(AU);
11691bc56edSDimitry Andric }
11791bc56edSDimitry Andric 
print(raw_ostream & OS,const Module *) const11891bc56edSDimitry Andric void MachineRegionInfoPass::print(raw_ostream &OS, const Module *) const {
11991bc56edSDimitry Andric   RI.print(OS);
12091bc56edSDimitry Andric }
12191bc56edSDimitry Andric 
12291bc56edSDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const1233ca95b02SDimitry Andric LLVM_DUMP_METHOD void MachineRegionInfoPass::dump() const {
12491bc56edSDimitry Andric   RI.dump();
12591bc56edSDimitry Andric }
12691bc56edSDimitry Andric #endif
12791bc56edSDimitry Andric 
12891bc56edSDimitry Andric char MachineRegionInfoPass::ID = 0;
1297a7e6055SDimitry Andric char &MachineRegionInfoPassID = MachineRegionInfoPass::ID;
13091bc56edSDimitry Andric 
1317a7e6055SDimitry Andric INITIALIZE_PASS_BEGIN(MachineRegionInfoPass, DEBUG_TYPE,
13291bc56edSDimitry Andric                       "Detect single entry single exit regions", true, true)
13391bc56edSDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
13491bc56edSDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachinePostDominatorTree)
13591bc56edSDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachineDominanceFrontier)
1367a7e6055SDimitry Andric INITIALIZE_PASS_END(MachineRegionInfoPass, DEBUG_TYPE,
13791bc56edSDimitry Andric                     "Detect single entry single exit regions", true, true)
13891bc56edSDimitry Andric 
13991bc56edSDimitry Andric // Create methods available outside of this file, to use them
14091bc56edSDimitry Andric // "include/llvm/LinkAllPasses.h". Otherwise the pass would be deleted by
14191bc56edSDimitry Andric // the link time optimization.
14291bc56edSDimitry Andric 
14391bc56edSDimitry Andric namespace llvm {
1446d97bb29SDimitry Andric 
createMachineRegionInfoPass()14591bc56edSDimitry Andric FunctionPass *createMachineRegionInfoPass() {
14691bc56edSDimitry Andric   return new MachineRegionInfoPass();
14791bc56edSDimitry Andric }
14891bc56edSDimitry Andric 
1496d97bb29SDimitry Andric } // end namespace llvm
150