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