11b8d8379SMatt Arsenault 
21b8d8379SMatt Arsenault #include "llvm/CodeGen/MachineRegionInfo.h"
31b8d8379SMatt Arsenault #include "llvm/CodeGen/MachinePostDominators.h"
41b8d8379SMatt Arsenault #include "llvm/ADT/Statistic.h"
51b8d8379SMatt Arsenault #include "llvm/Analysis/RegionInfoImpl.h"
61b8d8379SMatt Arsenault 
71b8d8379SMatt Arsenault using namespace llvm;
81b8d8379SMatt Arsenault 
91b8d8379SMatt Arsenault STATISTIC(numMachineRegions,       "The # of machine regions");
101b8d8379SMatt Arsenault STATISTIC(numMachineSimpleRegions, "The # of simple machine regions");
111b8d8379SMatt Arsenault 
121b8d8379SMatt Arsenault namespace llvm {
131b8d8379SMatt Arsenault template class RegionBase<RegionTraits<MachineFunction>>;
141b8d8379SMatt Arsenault template class RegionNodeBase<RegionTraits<MachineFunction>>;
151b8d8379SMatt Arsenault template class RegionInfoBase<RegionTraits<MachineFunction>>;
161b8d8379SMatt Arsenault }
171b8d8379SMatt Arsenault 
181b8d8379SMatt Arsenault //===----------------------------------------------------------------------===//
191b8d8379SMatt Arsenault // MachineRegion implementation
201b8d8379SMatt Arsenault //
211b8d8379SMatt Arsenault 
221b8d8379SMatt Arsenault MachineRegion::MachineRegion(MachineBasicBlock *Entry, MachineBasicBlock *Exit,
231b8d8379SMatt Arsenault                              MachineRegionInfo* RI,
241b8d8379SMatt Arsenault                              MachineDominatorTree *DT, MachineRegion *Parent) :
251b8d8379SMatt Arsenault   RegionBase<RegionTraits<MachineFunction>>(Entry, Exit, RI, DT, Parent) {
261b8d8379SMatt Arsenault 
271b8d8379SMatt Arsenault }
281b8d8379SMatt Arsenault 
291b8d8379SMatt Arsenault MachineRegion::~MachineRegion() { }
301b8d8379SMatt Arsenault 
311b8d8379SMatt Arsenault //===----------------------------------------------------------------------===//
321b8d8379SMatt Arsenault // MachineRegionInfo implementation
331b8d8379SMatt Arsenault //
341b8d8379SMatt Arsenault 
351b8d8379SMatt Arsenault MachineRegionInfo::MachineRegionInfo() :
361b8d8379SMatt Arsenault   RegionInfoBase<RegionTraits<MachineFunction>>() {
371b8d8379SMatt Arsenault 
381b8d8379SMatt Arsenault }
391b8d8379SMatt Arsenault 
401b8d8379SMatt Arsenault MachineRegionInfo::~MachineRegionInfo() {
411b8d8379SMatt Arsenault 
421b8d8379SMatt Arsenault }
431b8d8379SMatt Arsenault 
441b8d8379SMatt Arsenault void MachineRegionInfo::updateStatistics(MachineRegion *R) {
451b8d8379SMatt Arsenault   ++numMachineRegions;
461b8d8379SMatt Arsenault 
471b8d8379SMatt Arsenault   // TODO: Slow. Should only be enabled if -stats is used.
481b8d8379SMatt Arsenault   if (R->isSimple())
491b8d8379SMatt Arsenault     ++numMachineSimpleRegions;
501b8d8379SMatt Arsenault }
511b8d8379SMatt Arsenault 
52*74a53322SNAKAMURA Takumi void MachineRegionInfo::recalculate(MachineFunction &F,
531b8d8379SMatt Arsenault                                     MachineDominatorTree *DT_,
541b8d8379SMatt Arsenault                                     MachinePostDominatorTree *PDT_,
551b8d8379SMatt Arsenault                                     MachineDominanceFrontier *DF_) {
561b8d8379SMatt Arsenault   DT = DT_;
571b8d8379SMatt Arsenault   PDT = PDT_;
581b8d8379SMatt Arsenault   DF = DF_;
591b8d8379SMatt Arsenault 
601b8d8379SMatt Arsenault   MachineBasicBlock *Entry = GraphTraits<MachineFunction*>::getEntryNode(&F);
611b8d8379SMatt Arsenault 
621b8d8379SMatt Arsenault   TopLevelRegion = new MachineRegion(Entry, nullptr, this, DT, nullptr);
631b8d8379SMatt Arsenault   updateStatistics(TopLevelRegion);
641b8d8379SMatt Arsenault   calculate(F);
651b8d8379SMatt Arsenault }
661b8d8379SMatt Arsenault 
671b8d8379SMatt Arsenault //===----------------------------------------------------------------------===//
681b8d8379SMatt Arsenault // MachineRegionInfoPass implementation
691b8d8379SMatt Arsenault //
701b8d8379SMatt Arsenault 
711b8d8379SMatt Arsenault MachineRegionInfoPass::MachineRegionInfoPass() : MachineFunctionPass(ID) {
721b8d8379SMatt Arsenault   initializeMachineRegionInfoPassPass(*PassRegistry::getPassRegistry());
731b8d8379SMatt Arsenault }
741b8d8379SMatt Arsenault 
751b8d8379SMatt Arsenault MachineRegionInfoPass::~MachineRegionInfoPass() {
761b8d8379SMatt Arsenault 
771b8d8379SMatt Arsenault }
781b8d8379SMatt Arsenault 
791b8d8379SMatt Arsenault bool MachineRegionInfoPass::runOnMachineFunction(MachineFunction &F) {
801b8d8379SMatt Arsenault   releaseMemory();
811b8d8379SMatt Arsenault 
821b8d8379SMatt Arsenault   auto DT = &getAnalysis<MachineDominatorTree>();
831b8d8379SMatt Arsenault   auto PDT = &getAnalysis<MachinePostDominatorTree>();
841b8d8379SMatt Arsenault   auto DF = &getAnalysis<MachineDominanceFrontier>();
851b8d8379SMatt Arsenault 
861b8d8379SMatt Arsenault   RI.recalculate(F, DT, PDT, DF);
871b8d8379SMatt Arsenault   return false;
881b8d8379SMatt Arsenault }
891b8d8379SMatt Arsenault 
901b8d8379SMatt Arsenault void MachineRegionInfoPass::releaseMemory() {
911b8d8379SMatt Arsenault   RI.releaseMemory();
921b8d8379SMatt Arsenault }
931b8d8379SMatt Arsenault 
941b8d8379SMatt Arsenault void MachineRegionInfoPass::verifyAnalysis() const {
951b8d8379SMatt Arsenault   // Only do verification when user wants to, otherwise this expensive check
961b8d8379SMatt Arsenault   // will be invoked by PMDataManager::verifyPreservedAnalysis when
971b8d8379SMatt Arsenault   // a regionpass (marked PreservedAll) finish.
981b8d8379SMatt Arsenault   if (MachineRegionInfo::VerifyRegionInfo)
991b8d8379SMatt Arsenault     RI.verifyAnalysis();
1001b8d8379SMatt Arsenault }
1011b8d8379SMatt Arsenault 
1021b8d8379SMatt Arsenault void MachineRegionInfoPass::getAnalysisUsage(AnalysisUsage &AU) const {
1031b8d8379SMatt Arsenault   AU.setPreservesAll();
1041b8d8379SMatt Arsenault   AU.addRequiredTransitive<DominatorTreeWrapperPass>();
1051b8d8379SMatt Arsenault   AU.addRequired<PostDominatorTree>();
1061b8d8379SMatt Arsenault   AU.addRequired<DominanceFrontier>();
1071b8d8379SMatt Arsenault }
1081b8d8379SMatt Arsenault 
1091b8d8379SMatt Arsenault void MachineRegionInfoPass::print(raw_ostream &OS, const Module *) const {
1101b8d8379SMatt Arsenault   RI.print(OS);
1111b8d8379SMatt Arsenault }
1121b8d8379SMatt Arsenault 
113118b0c78SNAKAMURA Takumi #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1141b8d8379SMatt Arsenault void MachineRegionInfoPass::dump() const {
1151b8d8379SMatt Arsenault   RI.dump();
1161b8d8379SMatt Arsenault }
117118b0c78SNAKAMURA Takumi #endif
1181b8d8379SMatt Arsenault 
1191b8d8379SMatt Arsenault char MachineRegionInfoPass::ID = 0;
1201b8d8379SMatt Arsenault 
1211b8d8379SMatt Arsenault INITIALIZE_PASS_BEGIN(MachineRegionInfoPass, "regions",
1221b8d8379SMatt Arsenault                 "Detect single entry single exit regions", true, true)
1231b8d8379SMatt Arsenault INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
1241b8d8379SMatt Arsenault INITIALIZE_PASS_DEPENDENCY(MachinePostDominatorTree)
1251b8d8379SMatt Arsenault INITIALIZE_PASS_DEPENDENCY(MachineDominanceFrontier)
1261b8d8379SMatt Arsenault INITIALIZE_PASS_END(MachineRegionInfoPass, "regions",
1271b8d8379SMatt Arsenault                 "Detect single entry single exit regions", true, true)
1281b8d8379SMatt Arsenault 
1291b8d8379SMatt Arsenault // Create methods available outside of this file, to use them
1301b8d8379SMatt Arsenault // "include/llvm/LinkAllPasses.h". Otherwise the pass would be deleted by
1311b8d8379SMatt Arsenault // the link time optimization.
1321b8d8379SMatt Arsenault 
1331b8d8379SMatt Arsenault namespace llvm {
1341b8d8379SMatt Arsenault   FunctionPass *createMachineRegionInfoPass() {
1351b8d8379SMatt Arsenault     return new MachineRegionInfoPass();
1361b8d8379SMatt Arsenault   }
1371b8d8379SMatt Arsenault }
1381b8d8379SMatt Arsenault 
139