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