1*7ea69237SEugene Zelenko //===- lib/Codegen/MachineRegionInfo.cpp ----------------------------------===//
2*7ea69237SEugene Zelenko //
3*7ea69237SEugene Zelenko //                     The LLVM Compiler Infrastructure
4*7ea69237SEugene Zelenko //
5*7ea69237SEugene Zelenko // This file is distributed under the University of Illinois Open Source
6*7ea69237SEugene Zelenko // License. See LICENSE.TXT for details.
7*7ea69237SEugene Zelenko //
8*7ea69237SEugene Zelenko //===----------------------------------------------------------------------===//
9*7ea69237SEugene Zelenko 
101b8d8379SMatt Arsenault #include "llvm/ADT/Statistic.h"
111b8d8379SMatt Arsenault #include "llvm/Analysis/RegionInfoImpl.h"
12d9903888SChandler Carruth #include "llvm/CodeGen/MachinePostDominators.h"
13*7ea69237SEugene Zelenko #include "llvm/CodeGen/MachineRegionInfo.h"
14*7ea69237SEugene Zelenko #include "llvm/Pass.h"
15*7ea69237SEugene Zelenko #include "llvm/Support/Compiler.h"
16*7ea69237SEugene Zelenko #include "llvm/Support/Debug.h"
171b8d8379SMatt Arsenault 
1843130592SMatthias Braun #define DEBUG_TYPE "machine-region-info"
195e23fb86SRichard Smith 
201b8d8379SMatt Arsenault using namespace llvm;
211b8d8379SMatt Arsenault 
221b8d8379SMatt Arsenault STATISTIC(numMachineRegions,       "The # of machine regions");
231b8d8379SMatt Arsenault STATISTIC(numMachineSimpleRegions, "The # of simple machine regions");
241b8d8379SMatt Arsenault 
251b8d8379SMatt Arsenault namespace llvm {
26*7ea69237SEugene Zelenko 
271b8d8379SMatt Arsenault template class RegionBase<RegionTraits<MachineFunction>>;
281b8d8379SMatt Arsenault template class RegionNodeBase<RegionTraits<MachineFunction>>;
291b8d8379SMatt Arsenault template class RegionInfoBase<RegionTraits<MachineFunction>>;
30*7ea69237SEugene Zelenko 
31*7ea69237SEugene Zelenko } // end namespace llvm
321b8d8379SMatt Arsenault 
331b8d8379SMatt Arsenault //===----------------------------------------------------------------------===//
341b8d8379SMatt Arsenault // MachineRegion implementation
351b8d8379SMatt Arsenault 
361b8d8379SMatt Arsenault MachineRegion::MachineRegion(MachineBasicBlock *Entry, MachineBasicBlock *Exit,
371b8d8379SMatt Arsenault                              MachineRegionInfo* RI,
381b8d8379SMatt Arsenault                              MachineDominatorTree *DT, MachineRegion *Parent) :
39*7ea69237SEugene Zelenko   RegionBase<RegionTraits<MachineFunction>>(Entry, Exit, RI, DT, Parent) {}
401b8d8379SMatt Arsenault 
41*7ea69237SEugene Zelenko MachineRegion::~MachineRegion() = default;
421b8d8379SMatt Arsenault 
431b8d8379SMatt Arsenault //===----------------------------------------------------------------------===//
441b8d8379SMatt Arsenault // MachineRegionInfo implementation
451b8d8379SMatt Arsenault 
46*7ea69237SEugene Zelenko MachineRegionInfo::MachineRegionInfo() = default;
471b8d8379SMatt Arsenault 
48*7ea69237SEugene Zelenko MachineRegionInfo::~MachineRegionInfo() = default;
491b8d8379SMatt Arsenault 
501b8d8379SMatt Arsenault void MachineRegionInfo::updateStatistics(MachineRegion *R) {
511b8d8379SMatt Arsenault   ++numMachineRegions;
521b8d8379SMatt Arsenault 
531b8d8379SMatt Arsenault   // TODO: Slow. Should only be enabled if -stats is used.
541b8d8379SMatt Arsenault   if (R->isSimple())
551b8d8379SMatt Arsenault     ++numMachineSimpleRegions;
561b8d8379SMatt Arsenault }
571b8d8379SMatt Arsenault 
5874a53322SNAKAMURA Takumi void MachineRegionInfo::recalculate(MachineFunction &F,
591b8d8379SMatt Arsenault                                     MachineDominatorTree *DT_,
601b8d8379SMatt Arsenault                                     MachinePostDominatorTree *PDT_,
611b8d8379SMatt Arsenault                                     MachineDominanceFrontier *DF_) {
621b8d8379SMatt Arsenault   DT = DT_;
631b8d8379SMatt Arsenault   PDT = PDT_;
641b8d8379SMatt Arsenault   DF = DF_;
651b8d8379SMatt Arsenault 
661b8d8379SMatt Arsenault   MachineBasicBlock *Entry = GraphTraits<MachineFunction*>::getEntryNode(&F);
671b8d8379SMatt Arsenault 
681b8d8379SMatt Arsenault   TopLevelRegion = new MachineRegion(Entry, nullptr, this, DT, nullptr);
691b8d8379SMatt Arsenault   updateStatistics(TopLevelRegion);
701b8d8379SMatt Arsenault   calculate(F);
711b8d8379SMatt Arsenault }
721b8d8379SMatt Arsenault 
731b8d8379SMatt Arsenault //===----------------------------------------------------------------------===//
741b8d8379SMatt Arsenault // MachineRegionInfoPass implementation
751b8d8379SMatt Arsenault //
761b8d8379SMatt Arsenault 
771b8d8379SMatt Arsenault MachineRegionInfoPass::MachineRegionInfoPass() : MachineFunctionPass(ID) {
781b8d8379SMatt Arsenault   initializeMachineRegionInfoPassPass(*PassRegistry::getPassRegistry());
791b8d8379SMatt Arsenault }
801b8d8379SMatt Arsenault 
81*7ea69237SEugene Zelenko MachineRegionInfoPass::~MachineRegionInfoPass() = default;
821b8d8379SMatt Arsenault 
831b8d8379SMatt Arsenault bool MachineRegionInfoPass::runOnMachineFunction(MachineFunction &F) {
841b8d8379SMatt Arsenault   releaseMemory();
851b8d8379SMatt Arsenault 
861b8d8379SMatt Arsenault   auto DT = &getAnalysis<MachineDominatorTree>();
871b8d8379SMatt Arsenault   auto PDT = &getAnalysis<MachinePostDominatorTree>();
881b8d8379SMatt Arsenault   auto DF = &getAnalysis<MachineDominanceFrontier>();
891b8d8379SMatt Arsenault 
901b8d8379SMatt Arsenault   RI.recalculate(F, DT, PDT, DF);
9143130592SMatthias Braun 
9243130592SMatthias Braun   DEBUG(RI.dump());
9343130592SMatthias Braun 
941b8d8379SMatt Arsenault   return false;
951b8d8379SMatt Arsenault }
961b8d8379SMatt Arsenault 
971b8d8379SMatt Arsenault void MachineRegionInfoPass::releaseMemory() {
981b8d8379SMatt Arsenault   RI.releaseMemory();
991b8d8379SMatt Arsenault }
1001b8d8379SMatt Arsenault 
1011b8d8379SMatt Arsenault void MachineRegionInfoPass::verifyAnalysis() const {
1021b8d8379SMatt Arsenault   // Only do verification when user wants to, otherwise this expensive check
1031b8d8379SMatt Arsenault   // will be invoked by PMDataManager::verifyPreservedAnalysis when
1041b8d8379SMatt Arsenault   // a regionpass (marked PreservedAll) finish.
1051b8d8379SMatt Arsenault   if (MachineRegionInfo::VerifyRegionInfo)
1061b8d8379SMatt Arsenault     RI.verifyAnalysis();
1071b8d8379SMatt Arsenault }
1081b8d8379SMatt Arsenault 
1091b8d8379SMatt Arsenault void MachineRegionInfoPass::getAnalysisUsage(AnalysisUsage &AU) const {
1101b8d8379SMatt Arsenault   AU.setPreservesAll();
11143130592SMatthias Braun   AU.addRequired<MachineDominatorTree>();
11243130592SMatthias Braun   AU.addRequired<MachinePostDominatorTree>();
11343130592SMatthias Braun   AU.addRequired<MachineDominanceFrontier>();
11443130592SMatthias Braun   MachineFunctionPass::getAnalysisUsage(AU);
1151b8d8379SMatt Arsenault }
1161b8d8379SMatt Arsenault 
1171b8d8379SMatt Arsenault void MachineRegionInfoPass::print(raw_ostream &OS, const Module *) const {
1181b8d8379SMatt Arsenault   RI.print(OS);
1191b8d8379SMatt Arsenault }
1201b8d8379SMatt Arsenault 
121118b0c78SNAKAMURA Takumi #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
122eb2a2546SYaron Keren LLVM_DUMP_METHOD void MachineRegionInfoPass::dump() const {
1231b8d8379SMatt Arsenault   RI.dump();
1241b8d8379SMatt Arsenault }
125118b0c78SNAKAMURA Takumi #endif
1261b8d8379SMatt Arsenault 
1271b8d8379SMatt Arsenault char MachineRegionInfoPass::ID = 0;
128695e4374SJan Sjodin char &MachineRegionInfoPassID = MachineRegionInfoPass::ID;
1291b8d8379SMatt Arsenault 
13043130592SMatthias Braun INITIALIZE_PASS_BEGIN(MachineRegionInfoPass, DEBUG_TYPE,
1311b8d8379SMatt Arsenault                       "Detect single entry single exit regions", true, true)
1321b8d8379SMatt Arsenault INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
1331b8d8379SMatt Arsenault INITIALIZE_PASS_DEPENDENCY(MachinePostDominatorTree)
1341b8d8379SMatt Arsenault INITIALIZE_PASS_DEPENDENCY(MachineDominanceFrontier)
13543130592SMatthias Braun INITIALIZE_PASS_END(MachineRegionInfoPass, DEBUG_TYPE,
1361b8d8379SMatt Arsenault                     "Detect single entry single exit regions", true, true)
1371b8d8379SMatt Arsenault 
1381b8d8379SMatt Arsenault // Create methods available outside of this file, to use them
1391b8d8379SMatt Arsenault // "include/llvm/LinkAllPasses.h". Otherwise the pass would be deleted by
1401b8d8379SMatt Arsenault // the link time optimization.
1411b8d8379SMatt Arsenault 
1421b8d8379SMatt Arsenault namespace llvm {
143*7ea69237SEugene Zelenko 
1441b8d8379SMatt Arsenault FunctionPass *createMachineRegionInfoPass() {
1451b8d8379SMatt Arsenault   return new MachineRegionInfoPass();
1461b8d8379SMatt Arsenault }
1471b8d8379SMatt Arsenault 
148*7ea69237SEugene Zelenko } // end namespace llvm
149